/*
 * Copyright 1993 Robert J. Amstadt
 * Copyright 1995 Alexandre Julliard
 */

#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "wine/winbase16.h"
#include "winnt.h"
#include "heap.h"
#include "module.h"
#include "stackframe.h"
#include "selectors.h"
#include "builtin16.h"
#include "task.h"
#include "syslevel.h"
#include "debugtools.h"
#include "main.h"
#include "callback.h"

DEFAULT_DEBUG_CHANNEL(relay);

/***********************************************************************
 *           RELAY_Init
 */
BOOL RELAY_Init(void)
{
#ifdef __i386__
    WORD codesel;

      /* Allocate the code selector for CallTo16 routines */

    extern void Call16_Ret_Start(), Call16_Ret_End();
    extern void CallTo16_Ret();
    extern void CALL32_CBClient_Ret();
    extern void CALL32_CBClientEx_Ret();
    extern SEGPTR CallTo16_RetAddr;
    extern SEGPTR CALL32_CBClient_RetAddr;
    extern SEGPTR CALL32_CBClientEx_RetAddr;

    codesel = SELECTOR_AllocBlock( (void *)Call16_Ret_Start,
                                   (char *)Call16_Ret_End - (char *)Call16_Ret_Start,
                                   SEGMENT_CODE, TRUE, FALSE );
    if (!codesel) return FALSE;

      /* Patch the return addresses for CallTo16 routines */

    CallTo16_RetAddr = 
        PTR_SEG_OFF_TO_SEGPTR( codesel, (char*)CallTo16_Ret - (char*)Call16_Ret_Start );
    CALL32_CBClient_RetAddr = 
        PTR_SEG_OFF_TO_SEGPTR( codesel, (char*)CALL32_CBClient_Ret - (char*)Call16_Ret_Start );
    CALL32_CBClientEx_RetAddr = 
        PTR_SEG_OFF_TO_SEGPTR( codesel, (char*)CALL32_CBClientEx_Ret - (char*)Call16_Ret_Start );
#endif
    return TRUE;
}

/*
 * Stubs for the CallTo16/CallFrom16 routines on non-Intel architectures
 * (these will never be called but need to be present to satisfy the linker ...)
 */
#ifndef __i386__
WORD CALLBACK CallTo16Word( FARPROC16 target, INT nArgs )
{ assert( FALSE ); }

LONG CALLBACK CallTo16Long( FARPROC16 target, INT nArgs )
{ assert( FALSE ); }

void CALLBACK CallTo16RegisterShort( CONTEXT86 *context, INT nArgs )
{ assert( FALSE ); }

void CALLBACK CallTo16RegisterLong ( CONTEXT86 *context, INT nArgs )
{ assert( FALSE ); }

WORD CallFrom16Word( void )       
{ assert( FALSE ); }

LONG CallFrom16Long( void )       
{ assert( FALSE ); }

void CallFrom16Register( void )   
{ assert( FALSE ); }

void CallFrom16Thunk( void )      
{ assert( FALSE ); }

DWORD WINAPI CALL32_CBClient( FARPROC proc, LPWORD args, DWORD *esi )
{ assert( FALSE ); }

DWORD WINAPI CALL32_CBClientEx( FARPROC proc, LPWORD args, DWORD *esi, INT *nArgs )
{ assert( FALSE ); }
#endif


/* from relay32/relay386.c */
extern char **debug_relay_excludelist,**debug_relay_includelist;

/***********************************************************************
 *           RELAY_DebugCallFrom16
 */
void RELAY_DebugCallFrom16( CONTEXT86 *context )
{
    STACK16FRAME *frame;
    WORD ordinal;
    char *args16, funstr[80];
    const char *args;
    int i, usecdecl, reg_func;

    if (!TRACE_ON(relay)) return;

    frame = CURRENT_STACK16;
    args = BUILTIN_GetEntryPoint16( frame, funstr, &ordinal );
    if (!args) return; /* happens for the two snoop register relays */
    if (!RELAY_ShowDebugmsgRelay(funstr)) return;
    DPRINTF( "Call %s(",funstr);
    VA_START16( args16 );

    usecdecl = ( *args == 'c' );
    args += 2;
    reg_func = (    memcmp( args, "regs_", 5 ) == 0
                 || memcmp( args, "intr_", 5 ) == 0 );
    args += 5;

    if (usecdecl)
    {
        while (*args)
        {
            switch(*args)
            {
            case 'w':
            case 's':
                DPRINTF( "0x%04x", *(WORD *)args16 );
                args16 += 2;
                break;
            case 'l':
                DPRINTF( "0x%08x", *(int *)args16 );
                args16 += 4;
                break;
            case 'p':
                DPRINTF( "%04x:%04x", *(WORD *)(args16+2), *(WORD *)args16 );
                args16 += 4;
                break;
            case 't':
            case 'T':
                DPRINTF( "%04x:%04x %s", *(WORD *)(args16+2), *(WORD *)args16,
                         debugres_a( (LPSTR)PTR_SEG_TO_LIN(*(SEGPTR *)args16 )) );
                args16 += 4;
                break;
            }
            args++;
            if (*args) DPRINTF( "," );
        }
    }
    else  /* not cdecl */
    {
        /* Start with the last arg */
        for (i = 0; args[i]; i++)
        {
            switch(args[i])
            {
            case 'w':
            case 's':
                args16 += 2;
                break;
            case 'l':
            case 'p':
            case 't':
            case 'T':
                args16 += 4;
                break;
            }
        }

        while (*args)
        {
            switch(*args)
            {
            case 'w':
            case 's':
                args16 -= 2;
                DPRINTF( "0x%04x", *(WORD *)args16 );
                break;
            case 'l':
                args16 -= 4;
                DPRINTF( "0x%08x", *(int *)args16 );
                break;
            case 't':
                args16 -= 4;
                DPRINTF( "0x%08x %s", *(int *)args16,
                         debugres_a( (LPSTR)PTR_SEG_TO_LIN(*(SEGPTR *)args16 )));
                break;
            case 'p':
                args16 -= 4;
                DPRINTF( "%04x:%04x", *(WORD *)(args16+2), *(WORD *)args16 );
                break;
            case 'T':
                args16 -= 4;
                DPRINTF( "%04x:%04x %s", *(WORD *)(args16+2), *(WORD *)args16,
                         debugres_a( (LPSTR)PTR_SEG_TO_LIN(*(SEGPTR *)args16 )));
                break;
            }
            args++;
            if (*args) DPRINTF( "," );
        }
    }

    DPRINTF( ") ret=%04x:%04x ds=%04x\n", frame->cs, frame->ip, frame->ds );
    VA_END16( args16 );

    if (reg_func)
        DPRINTF("     AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x ES=%04x EFL=%08lx\n",
                AX_reg(context), BX_reg(context), CX_reg(context),
                DX_reg(context), SI_reg(context), DI_reg(context),
                (WORD)context->SegEs, context->EFlags );

    SYSLEVEL_CheckNotLevel( 2 );
}


/***********************************************************************
 *           RELAY_DebugCallFrom16Ret
 */
void RELAY_DebugCallFrom16Ret( CONTEXT86 *context, int ret_val )
{
    STACK16FRAME *frame;
    WORD ordinal;
    char funstr[80];
    const char *args;

    if (!TRACE_ON(relay)) return;
    frame = CURRENT_STACK16;
    args = BUILTIN_GetEntryPoint16( frame, funstr, &ordinal );
    if (!args) return;
    if (!RELAY_ShowDebugmsgRelay(funstr)) return;
    DPRINTF( "Ret  %s() ",funstr);

    if ( memcmp( args+2, "long_", 5 ) == 0 )
    {
        DPRINTF( "retval=0x%08x ret=%04x:%04x ds=%04x\n",
                 ret_val, frame->cs, frame->ip, frame->ds );
    }
    else if ( memcmp( args+2, "word_", 5 ) == 0 )
    {
        DPRINTF( "retval=0x%04x ret=%04x:%04x ds=%04x\n",
                 ret_val & 0xffff, frame->cs, frame->ip, frame->ds );
    }
    else if (    memcmp( args+2, "regs_", 5 ) == 0 
              || memcmp( args+2, "intr_", 5 ) == 0 )
    {
        DPRINTF("retval=none ret=%04x:%04x ds=%04x\n",
                (WORD)context->SegCs, LOWORD(context->Eip), (WORD)context->SegDs);
        DPRINTF("     AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x ES=%04x EFL=%08lx\n",
                AX_reg(context), BX_reg(context), CX_reg(context),
                DX_reg(context), SI_reg(context), DI_reg(context),
                (WORD)context->SegEs, context->EFlags );
    }

    SYSLEVEL_CheckNotLevel( 2 );
}


/***********************************************************************
 *           RELAY_Unimplemented16
 *
 * This function is called for unimplemented 16-bit entry points (declared
 * as 'stub' in the spec file).
 */
void RELAY_Unimplemented16(void)
{
    WORD ordinal;
    char name[80];
    STACK16FRAME *frame = CURRENT_STACK16;
    BUILTIN_GetEntryPoint16( frame, name, &ordinal );
    MESSAGE("FATAL: No handler for Win16 routine %s (called from %04x:%04x)\n",
            name, frame->cs, frame->ip );
    ExitProcess(1);
}


/***********************************************************************
 *           RELAY_DebugCallTo16
 *
 * 'target' contains either the function to call (normal CallTo16)
 * or a pointer to the CONTEXT86 struct (register CallTo16).
 * 'nb_args' is the number of argument bytes on the 16-bit stack; 
 * 'reg_func' specifies whether we have a register CallTo16 or not.
 */
void RELAY_DebugCallTo16( LPVOID target, int nb_args, BOOL reg_func )
{
    WORD *stack16;
    TEB *teb;

    if (!TRACE_ON(relay)) return;
    teb = NtCurrentTeb();
    stack16 = (WORD *)THREAD_STACK16(teb);

    nb_args /= sizeof(WORD);

    if ( reg_func )
    {
        CONTEXT86 *context = (CONTEXT86 *)target;

        DPRINTF("CallTo16(func=%04lx:%04x,ds=%04lx",
                context->SegCs, LOWORD(context->Eip), context->SegDs );
        while (nb_args--) DPRINTF( ",0x%04x", *--stack16 );
        DPRINTF(") ss:sp=%04x:%04x\n", SELECTOROF(teb->cur_stack),
                OFFSETOF(teb->cur_stack) );
        DPRINTF("     AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x BP=%04x ES=%04x FS=%04x\n",
                AX_reg(context), BX_reg(context), CX_reg(context),
                DX_reg(context), SI_reg(context), DI_reg(context),
                BP_reg(context), (WORD)context->SegEs, (WORD)context->SegFs );
    }
    else
    {
        DPRINTF("CallTo16(func=%04x:%04x,ds=%04x",
                HIWORD(target), LOWORD(target), SELECTOROF(teb->cur_stack) );
        while (nb_args--) DPRINTF( ",0x%04x", *--stack16 );
        DPRINTF(") ss:sp=%04x:%04x\n", SELECTOROF(teb->cur_stack),
                OFFSETOF(teb->cur_stack) );
    }

    SYSLEVEL_CheckNotLevel( 2 );
}


/***********************************************************************
 *           RELAY_DebugCallTo16Ret
 */
void RELAY_DebugCallTo16Ret( BOOL reg_func, int ret_val )
{
    if (!TRACE_ON(relay)) return;

    if (!reg_func)
    {
        DPRINTF("CallTo16() ss:sp=%04x:%04x retval=0x%08x\n", 
                SELECTOROF(NtCurrentTeb()->cur_stack),
                OFFSETOF(NtCurrentTeb()->cur_stack), ret_val);
    }
    else
    {
        CONTEXT86 *context = (CONTEXT86 *)ret_val;

        DPRINTF("CallTo16() ss:sp=%04x:%04x\n", 
                SELECTOROF(NtCurrentTeb()->cur_stack),
                OFFSETOF(NtCurrentTeb()->cur_stack));
        DPRINTF("     AX=%04x BX=%04x CX=%04x DX=%04x BP=%04x SP=%04x\n",
                AX_reg(context), BX_reg(context), CX_reg(context),
                DX_reg(context), BP_reg(context), LOWORD(context->Esp));
    }

    SYSLEVEL_CheckNotLevel( 2 );
}
