#include "strmini.h"
#include "ks.h"
#include <wingdi.h>
#include <mmreg.h>
#include "ksmedia.h"
#include "mpinit.h"
#include "dvhw32.h"

#define HW_ASM

extern DWORD luxbase;

////////////////////////////////////////////////////////

DWORD DVReadReg(DWORD off)
{
#ifdef HW_ASM
DWORD dwret= 0;

	_asm 
	{
	mov	eax,luxbase
	add	eax,off
	mov	eax,[eax]
	mov	dwret,eax
	}
	return dwret;
#else

DWORD *dwaddr;

	dwaddr = (DWORD *)(luxbase + off);
	return *dwaddr;

#endif
}

////////////////////////////////////////////////////////

DWORD DVReadDRAM(DWORD off)
{
#ifdef HW_ASM
DWORD dwret= 0;

	_asm 
	{
	mov	eax,luxbase
	add	eax,off
	mov	eax,[eax]
	mov	dwret,eax
	}
	return dwret;
#else

DWORD *dwaddr;

	dwaddr = (DWORD *)(luxbase + off);
	return *dwaddr;

#endif
}

////////////////////////////////////////////////////////

void DVWriteDRAM(DWORD off,DWORD da)
{
#ifdef HW_ASM
	_asm {
	push	ebx
	mov	ebx,luxbase
	add	ebx,off
	mov	eax, da
	mov	[ebx],eax
	pop	ebx
	}
#else

DWORD *dwaddr = NULL;
	dwaddr = (DWORD *)((DWORD)luxbase + off);
	*dwaddr = da;

#endif
}

////////////////////////////////////////////////////////

void DVWriteREG(DWORD off,DWORD da)
{
#ifdef HW_ASM
	_asm {
	push	ebx
	mov	ebx,luxbase
	add	ebx,off
	mov	eax, da
	mov	[ebx],eax
	pop	ebx
	}
#else

DWORD *dwaddr = NULL;
	dwaddr = (DWORD *)((DWORD)luxbase + off);
	*dwaddr = da;

#endif
}

////////////////////////////////////////////////////////

void DVStoreStr(DWORD off,DWORD val,DWORD cnt)
{
#ifdef HW_ASM
	_asm {
	push    edi
	push    ecx

	cld
	mov	edi,luxbase
	add	edi,off
	mov	ecx,cnt

	shr	ecx,2
	jecxz	store_30

	mov	eax,val
	rep stosd

store_30:

	pop	ecx
	pop	edi
	}
#else

DWORD dwcount=0, dwloop=0;
DWORD *dwdst = NULL;

	dwcount = (DWORD)(cnt >> 2);
	dwdst = (DWORD *)((DWORD)luxbase + off);

	for(dwloop=0; dwloop < dwcount; dwloop++)
		*dwdst++ = val;
#endif
}

////////////////////////////////////////////////////////

void DVMoveStr(DWORD doff,DWORD soff,DWORD cnt)
{
#ifdef HW_ASM
	_asm {
	push	edi
	push	esi
	push	edx
	push	ecx

	cld
	mov		edi,luxbase
	mov		esi,soff
	add		edi,doff

	mov		edx,edi
	and		edx,3	
	jz		move_5
	
	mov		ecx,4		
	sub		ecx,edx
	mov		edx,ecx
	rep movsb

move_5:
	mov		ecx,cnt
	sub		ecx,edx
	jbe		done			// cnt may be less than 3
	shr		ecx,2
	jecxz move_10
	rep movsd

move_10:

	mov		ecx,cnt
	sub		ecx,edx
	and		ecx,3
	jecxz done
	rep movsb

done:
	pop		ecx
	pop		edx
	pop		esi
	pop		edi
	}
#else

DWORD *dwdst=NULL;
DWORD *dwsrc=NULL;
DWORD dwcount=0, dwloop=0;
int bcount=0, loop=0;
BYTE *bdst=NULL;
BYTE *bsrc=NULL;

	dwdst = (DWORD *)((DWORD)luxbase + doff);
	dwsrc = (DWORD *)soff;

	dwcount = (DWORD)(cnt >> 2);
	for(dwloop=0; dwloop < dwcount; dwloop++) 
	{
		*dwdst++ = *dwsrc++;
	}

	bdst = (BYTE *)dwdst;
	bsrc = (BYTE *)dwsrc;

	bcount = (int)(cnt & 0x3);
	for(loop=0; loop < bcount; loop++)
		*bdst++ = *bsrc++;

#endif
}

////////////////////////////////////////////////////////

void DVReadStr(DWORD doff,DWORD soff,DWORD cnt)
{
#ifdef HW_ASM
	_asm {
	push	edi
	push	esi
	push	edx
	push	ecx

	cld
	mov	esi,luxbase
	add	esi,soff
	mov	edi,doff
	mov	ecx,cnt

	and ecx,3
	jecxz read_10
	rep movsb

read_10:

	mov ecx,cnt
	shr ecx,2
	jecxz done
	rep movsd

done:
	pop	ecx
	pop	edx
	pop	esi
	pop	edi
	}
#else

DWORD *dwdst;
DWORD *dwsrc;
DWORD dwcount, dwloop;
BYTE *bdst=NULL;
BYTE *bsrc=NULL;

	dwsrc = (DWORD *)((DWORD)luxbase + soff);
	dwdst = (DWORD *)doff;

	dwcount = (DWORD)(cnt >> 2);
	for(dwloop=0; dwloop < dwcount; dwloop++)
	{
		*dwdst++ = *dwsrc++;
	}

	bdst = (BYTE *)dwdst;
	bsrc = (BYTE *)dwsrc;
	
	dwcount = cnt & 0x3;
	for(dwloop=0; dwloop < dwcount; dwloop++)
		*bdst++ = *bsrc++;

#endif
}

////////////////////////////////////////////////////////
