/*
 * Emulation of priviledged instructions
 *
 * Copyright 1995 Alexandre Julliard
 */

#include <stdio.h>
#include "windows.h"
#include "ldt.h"
#include "miscemu.h"
#include "sig_context.h"


#define STACK_sig(context) \
   ((GET_SEL_FLAGS(SS_sig(context)) & LDT_FLAGS_32BIT) ? \
                   ESP_sig(context) : SP_sig(context))

#define STACK_PTR(context) \
    (PTR_SEG_OFF_TO_LIN(SS_sig(context),STACK_sig(context)))

/***********************************************************************
 *           INSTR_ReplaceSelector
 *
 * Try to replace an invalid selector by a valid one.
 * The only selector where it is allowed to do "mov ax,40;mov es,ax"
 * is the so called 'bimodal' selector 0x40, which points to the BIOS
 * data segment. Used by (at least) Borland products (and programs compiled 
 * using Borland products).
 *
 * See Undocumented Windows, Chapter 5, __0040.
 */
static WORD INSTR_ReplaceSelector( SIGCONTEXT *context, WORD sel)
{
    if (sel == 0x40)
    {
        static WORD sys_timer = 0;
        if (!sys_timer)
            sys_timer = CreateSystemTimer( 55, (FARPROC16)DOSMEM_Tick );
        return DOSMEM_BiosSeg;
    }
    return 0;  /* Can't replace selector, crashdump */
}


/***********************************************************************
 *           INSTR_GetOperandAddr
 *
 * Return the address of an instruction operand (from the mod/rm byte).
 */
static BYTE *INSTR_GetOperandAddr( SIGCONTEXT *context, BYTE *instr,
                                   int long_addr, int segprefix, int *len )
{
    int mod, rm, base, index = 0, ss = 0, seg = 0, off;

#define GET_VAL(val,type) \
    { *val = *(type *)instr; instr += sizeof(type); *len += sizeof(type); }

    *len = 0;
    GET_VAL( &mod, BYTE );
    rm = mod & 7;
    mod >>= 6;

    if (mod == 3)
    {
        switch(rm)
        {
        case 0: return (BYTE *)&EAX_sig(context);
        case 1: return (BYTE *)&ECX_sig(context);
        case 2: return (BYTE *)&EDX_sig(context);
        case 3: return (BYTE *)&EBX_sig(context);
        case 4: return (BYTE *)&ESP_sig(context);
        case 5: return (BYTE *)&EBP_sig(context);
        case 6: return (BYTE *)&ESI_sig(context);
        case 7: return (BYTE *)&EDI_sig(context);
        }
    }

    if (long_addr)
    {
        if (rm == 4)
        {
            BYTE sib;
            GET_VAL( &sib, BYTE );
            rm = sib & 7;
            ss = sib >> 6;
            switch(sib >> 3)
            {
            case 0: index = EAX_sig(context); break;
            case 1: index = ECX_sig(context); break;
            case 2: index = EDX_sig(context); break;
            case 3: index = EBX_sig(context); break;
            case 4: index = 0; break;
            case 5: index = EBP_sig(context); break;
            case 6: index = ESI_sig(context); break;
            case 7: index = EDI_sig(context); break;
            }
        }

        switch(rm)
        {
        case 0: base = EAX_sig(context); seg = DS_sig(context); break;
        case 1: base = ECX_sig(context); seg = DS_sig(context); break;
        case 2: base = EDX_sig(context); seg = DS_sig(context); break;
        case 3: base = EBX_sig(context); seg = DS_sig(context); break;
        case 4: base = ESP_sig(context); seg = SS_sig(context); break;
        case 5: base = EBP_sig(context); seg = SS_sig(context); break;
        case 6: base = ESI_sig(context); seg = DS_sig(context); break;
        case 7: base = EDI_sig(context); seg = DS_sig(context); break;
        }
        switch (mod)
        {
        case 0:
            if (rm == 5)  /* special case: ds:(disp32) */
            {
                GET_VAL( &base, DWORD );
                seg = DS_sig(context);
            }
            break;

        case 1:  /* 8-bit disp */
            GET_VAL( &off, BYTE );
            base += (signed char)off;
            break;

        case 2:  /* 32-bit disp */
            GET_VAL( &off, DWORD );
            base += (signed long)off;
            break;
        }
    }
    else  /* short address */
    {
        switch(rm)
        {
        case 0:  /* ds:(bx,si) */
            base = BX_sig(context) + SI_sig(context);
            seg  = DS_sig(context);
            break;
        case 1:  /* ds:(bx,di) */
            base = BX_sig(context) + DI_sig(context);
            seg  = DS_sig(context);
            break;
        case 2:  /* ss:(bp,si) */
            base = BP_sig(context) + SI_sig(context);
            seg  = SS_sig(context);
            break;
        case 3:  /* ss:(bp,di) */
            base = BP_sig(context) + DI_sig(context);
            seg  = SS_sig(context);
            break;
        case 4:  /* ds:(si) */
            base = SI_sig(context);
            seg  = DS_sig(context);
            break;
        case 5:  /* ds:(di) */
            base = DI_sig(context);
            seg  = DS_sig(context);
            break;
        case 6:  /* ss:(bp) */
            base = BP_sig(context);
            seg  = SS_sig(context);
            break;
        case 7:  /* ds:(bx) */
            base = BX_sig(context);
            seg  = DS_sig(context);
            break;
        }

        switch(mod)
        {
        case 0:
            if (rm == 6)  /* special case: ds:(disp16) */
            {
                GET_VAL( &base, WORD );
                seg  = DS_sig(context);
            }
            break;

        case 1:  /* 8-bit disp */
            GET_VAL( &off, BYTE );
            base += (signed char)off;
            break;

        case 2:  /* 16-bit disp */
            GET_VAL( &off, WORD );
            base += (signed short)off;
            break;
        }
        base &= 0xffff;
    }
    if (segprefix != -1) seg = segprefix;

    /* Make sure the segment and offset are valid */
    if (((seg & 7) != 7) || IS_SELECTOR_FREE(seg)) return NULL;
    if (GET_SEL_LIMIT(seg) < (base + (index << ss))) return NULL;
    return (BYTE *)PTR_SEG_OFF_TO_LIN( seg, (base + (index << ss)) );
#undef GET_VAL
}


/***********************************************************************
 *           INSTR_EmulateLDS
 *
 * Emulate the LDS (and LES,LFS,etc.) instruction.
 */
static BOOL32 INSTR_EmulateLDS( SIGCONTEXT *context, BYTE *instr, int long_op,
                                int long_addr, int segprefix, int *len )
{
    WORD seg;
    BYTE *regmodrm = instr + 1 + (*instr == 0x0f);
    BYTE *addr = INSTR_GetOperandAddr( context, regmodrm,
                                       long_addr, segprefix, len );
    if (!addr)
        return FALSE;  /* Unable to emulate it */
    seg = *(WORD *)(addr + (long_op ? 4 : 2));

    if (!(seg = INSTR_ReplaceSelector( context, seg )))
        return FALSE;  /* Unable to emulate it */

    /* Now store the offset in the correct register */

    switch((*regmodrm >> 3) & 7)
    {
    case 0:
        if (long_op) EAX_sig(context) = *(DWORD *)addr;
        else AX_sig(context) = *(WORD *)addr;
        break;
    case 1:
        if (long_op) ECX_sig(context) = *(DWORD *)addr;
        else CX_sig(context) = *(WORD *)addr;
        break;
    case 2:
        if (long_op) EDX_sig(context) = *(DWORD *)addr;
        else DX_sig(context) = *(WORD *)addr;
        break;
    case 3:
        if (long_op) EBX_sig(context) = *(DWORD *)addr;
        else BX_sig(context) = *(WORD *)addr;
        break;
    case 4:
        if (long_op) ESP_sig(context) = *(DWORD *)addr;
        else SP_sig(context) = *(WORD *)addr;
        break;
    case 5:
        if (long_op) EBP_sig(context) = *(DWORD *)addr;
        else BP_sig(context) = *(WORD *)addr;
        break;
    case 6:
        if (long_op) ESI_sig(context) = *(DWORD *)addr;
        else SI_sig(context) = *(WORD *)addr;
        break;
    case 7:
        if (long_op) EDI_sig(context) = *(DWORD *)addr;
        else DI_sig(context) = *(WORD *)addr;
        break;
    }

    /* Store the correct segment in the segment register */

    switch(*instr)
    {
    case 0xc4: ES_sig(context) = seg; break;  /* les */
    case 0xc5: DS_sig(context) = seg; break;  /* lds */
    case 0x0f: switch(instr[1])
               {
               case 0xb2: SS_sig(context) = seg; break;  /* lss */
#ifdef FS_sig
               case 0xb4: FS_sig(context) = seg; break;  /* lfs */
#endif
#ifdef GS_sig
               case 0xb5: GS_sig(context) = seg; break;  /* lgs */
#endif
               }
               break;
    }

    /* Add the opcode size to the total length */

    *len += 1 + (*instr == 0x0f);
    return TRUE;
}


/***********************************************************************
 *           INSTR_EmulateInstruction
 *
 * Emulate a priviledged instruction. Returns TRUE if emulation successful.
 */
BOOL32 INSTR_EmulateInstruction( SIGCONTEXT *context )
{
    int prefix, segprefix, prefixlen, len, repX, long_op, long_addr;
    BYTE *instr;

    long_op = long_addr = (GET_SEL_FLAGS(CS_sig(context)) & LDT_FLAGS_32BIT) != 0;
    instr = (BYTE *) PTR_SEG_OFF_TO_LIN( CS_sig(context), EIP_sig(context) );

    /* First handle any possible prefix */

    segprefix = -1;  /* no prefix */
    prefix = 1;
    repX = 0;
    prefixlen = 0;
    while(prefix)
    {
        switch(*instr)
        {
        case 0x2e:
            segprefix = CS_sig(context);
            break;
        case 0x36:
            segprefix = SS_sig(context);
            break;
        case 0x3e:
            segprefix = DS_sig(context);
            break;
        case 0x26:
            segprefix = ES_sig(context);
            break;
#ifdef FS_sig
        case 0x64:
            segprefix = FS_sig(context);
            break;
#endif
#ifdef GS_sig
        case 0x65:
            segprefix = GS_sig(context);
            break;
#endif
        case 0x66:
            long_op = !long_op;  /* opcode size prefix */
            break;
        case 0x67:
            long_addr = !long_addr;  /* addr size prefix */
            break;
        case 0xf0:  /* lock */
	    break;
        case 0xf2:  /* repne */
	    repX = 1;
	    break;
        case 0xf3:  /* repe */
	    repX = 2;
            break;
        default:
            prefix = 0;  /* no more prefixes */
            break;
        }
        if (prefix)
        {
            instr++;
            prefixlen++;
        }
    }

    /* Now look at the actual instruction */

    switch(*instr)
    {
        case 0x07: /* pop es */
        case 0x17: /* pop ss */
        case 0x1f: /* pop ds */
            {
                WORD seg = *(WORD *)STACK_PTR( context );
                if ((seg = INSTR_ReplaceSelector( context, seg )) != 0)
                {
                    switch(*instr)
                    {
                    case 0x07: ES_sig(context) = seg; break;
                    case 0x17: SS_sig(context) = seg; break;
                    case 0x1f: DS_sig(context) = seg; break;
                    }
                    STACK_sig(context) += long_op ? 4 : 2;
                    EIP_sig(context) += prefixlen + 1;
                    return TRUE;
                }
            }
            break;  /* Unable to emulate it */

        case 0x0f: /* extended instruction */
            switch(instr[1])
            {
#ifdef FS_sig
            case 0xa1: /* pop fs */
                {
                    WORD seg = *(WORD *)STACK_PTR( context );
                    if ((seg = INSTR_ReplaceSelector( context, seg )) != 0)
                    {
                        FS_sig(context) = seg;
                        STACK_sig(context) += long_op ? 4 : 2;
                        EIP_sig(context) += prefixlen + 2;
                        return TRUE;
                    }
                }
                break;
#endif  /* FS_sig */

#ifdef GS_sig
            case 0xa9: /* pop gs */
                {
                    WORD seg = *(WORD *)STACK_PTR( context );
                    if ((seg = INSTR_ReplaceSelector( context, seg )) != 0)
                    {
                        GS_sig(context) = seg;
                        STACK_sig(context) += long_op ? 4 : 2;
                        EIP_sig(context) += prefixlen + 2;
                        return TRUE;
                    }
                }
                break;
#endif  /* GS_sig */

            case 0xb2: /* lss addr,reg */
#ifdef FS_sig
            case 0xb4: /* lfs addr,reg */
#endif
#ifdef GS_sig
            case 0xb5: /* lgs addr,reg */
#endif
                if (INSTR_EmulateLDS( context, instr, long_op,
                                      long_addr, segprefix, &len ))
                {
                    EIP_sig(context) += prefixlen + len;
                    return TRUE;
                }
                break;
            }
            break;  /* Unable to emulate it */

        case 0x6c: /* insb     */
        case 0x6d: /* insw/d   */
        case 0x6e: /* outsb    */
        case 0x6f: /* outsw/d  */
	    {
	      int typ = *instr;  /* Just in case it's overwritten.  */
	      int outp = (typ >= 0x6e);
	      unsigned long count = repX ?
                          (long_addr ? ECX_sig(context) : CX_sig(context)) : 1;
	      int opsize = (typ & 1) ? (long_op ? 4 : 2) : 1;
	      int step = (EFL_sig(context) & 0x400) ? -opsize : +opsize;
	      int seg = outp ? DS_sig(context) : ES_sig(context);  /* FIXME: is this right? */

	      if (outp)
		/* FIXME: Check segment readable.  */
		(void)0;
	      else
		/* FIXME: Check segment writeable.  */
		(void)0;

	      if (repX)
		if (long_addr)
		  ECX_sig(context) = 0;
		else
		  CX_sig(context) = 0;

	      while (count-- > 0)
		{
		  void *data;
		  if (outp)
                  {
		      data = PTR_SEG_OFF_TO_LIN (seg,
                               long_addr ? ESI_sig(context) : SI_sig(context));
		      if (long_addr) ESI_sig(context) += step;
		      else SI_sig(context) += step;
                  }
		  else
                  {
		      data = PTR_SEG_OFF_TO_LIN (seg,
                               long_addr ? EDI_sig(context) : DI_sig(context));
		      if (long_addr) EDI_sig(context) += step;
		      else DI_sig(context) += step;
                  }
                  
		  switch (typ)
                  {
		    case 0x6c:
		      *((BYTE *)data) = IO_inport( DX_sig(context), 1);
		      break;
		    case 0x6d:
		      if (long_op)
			*((DWORD *)data) = IO_inport( DX_sig(context), 4);
		      else
			*((WORD *)data) = IO_inport( DX_sig(context), 2);
		      break;
		    case 0x6e:
                        IO_outport( DX_sig(context), 1, *((BYTE *)data));
                        break;
		    case 0x6f:
                        if (long_op)
                            IO_outport( DX_sig(context), 4, *((DWORD *)data));
                        else
                            IO_outport( DX_sig(context), 2, *((WORD *)data));
                        break;
		    }
		}
              EIP_sig(context) += prefixlen + 1;
	    }
            return TRUE;

        case 0x8e: /* mov XX,segment_reg */
            {
                WORD seg;
                BYTE *addr = INSTR_GetOperandAddr(context, instr + 1,
                                                  long_addr, segprefix, &len );
                if (!addr)
                    break;  /* Unable to emulate it */
                seg = *(WORD *)addr;
                if (!(seg = INSTR_ReplaceSelector( context, seg )))
                    break;  /* Unable to emulate it */

                switch((instr[1] >> 3) & 7)
                {
                case 0:
                    ES_sig(context) = seg;
                    EIP_sig(context) += prefixlen + len + 1;
                    return TRUE;
                case 1:  /* cs */
                    break;
                case 2:
                    SS_sig(context) = seg;
                    EIP_sig(context) += prefixlen + len + 1;
                    return TRUE;
                case 3:
                    DS_sig(context) = seg;
                    EIP_sig(context) += prefixlen + len + 1;
                    return TRUE;
                case 4:
#ifdef FS_sig
                    FS_sig(context) = seg;
                    EIP_sig(context) += prefixlen + len + 1;
                    return TRUE;
#endif
                case 5:
#ifdef GS_sig
                    GS_sig(context) = seg;
                    EIP_sig(context) += prefixlen + len + 1;
                    return TRUE;
#endif
                case 6:  /* unused */
                case 7:  /* unused */
                    break;
                }
            }
            break;  /* Unable to emulate it */

        case 0xc4: /* les addr,reg */
        case 0xc5: /* lds addr,reg */
            if (INSTR_EmulateLDS( context, instr, long_op,
                                  long_addr, segprefix, &len ))
            {
                EIP_sig(context) += prefixlen + len;
                return TRUE;
            }
            break;  /* Unable to emulate it */
            
        case 0xcd: /* int <XX> */
            if (long_op)
            {
                fprintf(stderr, "int xx from 32-bit code is not supported.\n");
                break;  /* Unable to emulate it */
            }
            else
            {
                FARPROC16 addr = INT_GetHandler( instr[1] );
                WORD *stack = (WORD *)STACK_PTR( context );
                /* Push the flags and return address on the stack */
                *(--stack) = FL_sig(context);
                *(--stack) = CS_sig(context);
                *(--stack) = IP_sig(context) + prefixlen + 2;
                STACK_sig(context) -= 3 * sizeof(WORD);
                /* Jump to the interrupt handler */
                CS_sig(context)  = HIWORD(addr);
                EIP_sig(context) = LOWORD(addr);
            }
            return TRUE;

        case 0xcf: /* iret */
            if (long_op)
            {
                DWORD *stack = (DWORD *)STACK_PTR( context );
                EIP_sig(context) = *stack++;
                CS_sig(context)  = *stack++;
                EFL_sig(context) = *stack;
                STACK_sig(context) += 3*sizeof(DWORD);  /* Pop the return address and flags */
            }
            else
            {
                WORD *stack = (WORD *)STACK_PTR( context );
                EIP_sig(context) = *stack++;
                CS_sig(context)  = *stack++;
                FL_sig(context)  = *stack;
                STACK_sig(context) += 3*sizeof(WORD);  /* Pop the return address and flags */
            }
            return TRUE;

        case 0xe4: /* inb al,XX */
            AL_sig(context) = IO_inport( instr[1], 1 );
	    EIP_sig(context) += prefixlen + 2;
            return TRUE;

        case 0xe5: /* in (e)ax,XX */
            if (long_op) EAX_sig(context) = IO_inport( instr[1], 4 );
            else AX_sig(context) = IO_inport( instr[1], 2 );
	    EIP_sig(context) += prefixlen + 2;
            return TRUE;

        case 0xe6: /* outb XX,al */
            IO_outport( instr[1], 1, AL_sig(context) );
	    EIP_sig(context) += prefixlen + 2;
            return TRUE;

        case 0xe7: /* out XX,(e)ax */
            if (long_op) IO_outport( instr[1], 4, EAX_sig(context) );
            else IO_outport( instr[1], 2, AX_sig(context) );
  	    EIP_sig(context) += prefixlen + 2;
            return TRUE;

        case 0xec: /* inb al,dx */
            AL_sig(context) = IO_inport( DX_sig(context), 1 );
  	    EIP_sig(context) += prefixlen + 1;
            return TRUE;

        case 0xed: /* in (e)ax,dx */
            if (long_op) EAX_sig(context) = IO_inport( DX_sig(context), 4 );
            else AX_sig(context) = IO_inport( DX_sig(context), 2 );
  	    EIP_sig(context) += prefixlen + 1;
            return TRUE;

        case 0xee: /* outb dx,al */
            IO_outport( DX_sig(context), 1, AL_sig(context) );
  	    EIP_sig(context) += prefixlen + 1;
            return TRUE;
      
        case 0xef: /* out dx,(e)ax */
            if (long_op) IO_outport( DX_sig(context), 4, EAX_sig(context) );
            else IO_outport( DX_sig(context), 2, AX_sig(context) );
  	    EIP_sig(context) += prefixlen + 1;
            return TRUE;

        case 0xfa: /* cli, ignored */
  	    EIP_sig(context) += prefixlen + 1;
            return TRUE;

        case 0xfb: /* sti, ignored */
  	    EIP_sig(context) += prefixlen + 1;
            return TRUE;
    }
    fprintf(stderr, "Unexpected Windows program segfault"
                    " - opcode = %x\n", *instr);
    return FALSE;  /* Unable to emulate it */
}
