/***************************************************************************

    M.A.M.E.32  -  Multiple Arcade Machine Emulator for Win32
    Win32 Portions Copyright (C) 1997-98 Michael Soderstrom and Chris Kirmse
    
    This file is part of MAME32, and may only be used, modified and
    distributed under the terms of the MAME license, in "readme.txt".
    By continuing to use, modify or distribute this file you indicate
    that you have read the license and understand and accept it fully.

 ***************************************************************************/

#ifndef __OSINLINE__
#define __OSINLINE__

/* What goes herein depends heavily on the OS. */

//#include "dirty.h"
/* Clean dirty method */
//#define osd_mark_vector_dirty(x, y) MarkDirtyPixel(x,y);
#define osd_mark_vector_dirty(x, y)

#if defined(_M_IX86) && defined(_MSC_VER)

#define vec_mult _vec_mult
inline int _vec_mult(int x, int y)
{
    int result;
    __asm
    {
        mov eax , x
        imul y
        mov result , edx
    }
    return result;
}

#if _MSC_VER < 0x0400
INLINE unsigned int osd_cycles(void)
{
    int result;

#define ASM_RDTSC __asm _emit 0x0f __asm _emit 0x31

    __asm
    {
        xor eax, eax        /* touch eax so compiler will not use it. */
        ASM_RDTSC           /* load clock cycle counter in eax and edx */
        mov result, eax     /* the result has to go in eax (low 32 bits) */
    }

    return result;
}
#else
INLINE unsigned int osd_cycles(void)
{
    int result;

    __asm
    {
        rdtsc               /* load clock cycle counter in eax and edx */
        mov result, eax     /* the result has to go in eax (low 32 bits) */
    }

    return result;
}

#endif /* _MSC_VER */

#elif defined(__GNUC__)

#define vec_mult _vec_mult
INLINE int _vec_mult(int x, int y)
{
    int result;
    __asm__ (
            "movl  %1    , %0    ; "
            "imull %2            ; "    /* do the multiply */
            "movl  %%edx , %%eax ; "
            :  "=&a" (result)           /* the result has to go in eax */
            :  "mr" (x),                /* x and y can be regs or mem */
               "mr" (y)
            :  "%edx", "%cc"            /* clobbers edx and flags */
        );
    return result;
}

INLINE unsigned int osd_cycles(void)
{
    int result;

    __asm__ __volatile__ (
        "rdtsc                 \n"  /* load clock cycle counter in eax and edx */
        :  "=&a" (result)           /* the result has to go in eax */
        :                           /* no inputs */
        :  "%edx"                   /* clobbers edx */
    );

    return result;
}

#else

#include "ticker.h"

INLINE unsigned int osd_cycles(void)
{
    return ticker();
}

#endif

/* for asmtile.asm */
#include "win32.h"
//============================================================
//	PROTOTYPES
//============================================================
void __osd_pend(void);
void osd_pdo16( UINT16 *dest, const UINT16 *source, int count, UINT8 *pri, UINT32 pcode );
void osd_pdt16( UINT16 *dest, const UINT16 *source, const UINT8 *pMask, int mask, int value, int count, UINT8 *pri, UINT32 pcode );
void osd_pdt16np( UINT16 *dest, const UINT16 *source, const UINT8 *pMask, int mask, int value, int count, UINT8 *pri, UINT32 pcode );

extern void (*_osd_pend)(void);
extern void (*_osd_pdo16)( UINT16 *dest, const UINT16 *source, int count, UINT8 *pri, UINT32 pcode );
extern void (*_osd_pdt16)( UINT16 *dest, const UINT16 *source, const UINT8 *pMask, int mask, int value, int count, UINT8 *pri, UINT32 pcode );
extern void (*_osd_pdt16np)( UINT16 *dest, const UINT16 *source, const UINT8 *pMask, int mask, int value, int count, UINT8 *pri, UINT32 pcode );
//============================================================
//	MACROS
//============================================================

#define osd_pend	_osd_pend
#define pdo16		_osd_pdo16
#define pdt16		_osd_pdt16
#define pdt16np		_osd_pdt16np
#endif /* __OSINLINE__ */
