//video.c
#include <windows.h>
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include "ls220.h"
#include "iic.h"
#include "video.h"
#include "dvhw32.h"
#include "audio.h"

//#define LINE21

int	m_noVideo = 0;

//global declarations
DWORD	luxbase;
BOOL	m_eprom = FALSE;
BOOL	m_spdif		= FALSE;
BOOL	isStillMenu;
BYTE	v_m_VPM;
BYTE	v_m_Letter;
BYTE	v_m_comp;		// COMP or S-VIDEO
BOOL	v_m_mpeg1;
BOOL	v_m_PanScan;
BYTE	v_m_tvencoder;
BOOL	v_m_fullscrn;
BYTE	v_m_aps;
int		v_m_speed;
WORD	width = 720;
WORD	height = 480;
WORD	v_remainder;
DWORD	v_wptr;
DWORD	v_m_total;
DWORD	v_PTS;
int		v_m_vga;
DWORD	v_m_frame_period = 0x5940bb8;	// 90kHz / 30(frms)
BOOL	v_m_VideoSrc_NTSC = TRUE;	// Video Src
DWORD	HW_WRAP_AROUND = 0xf00000;
BYTE	orig_tvout;
BOOL	v_m_zoomin = FALSE;
BOOL	isMenu;
BOOL	b_LetterBox = 0;

int		m_gamma = 0;	// what is initial value ?!
int		m_chroma = 0;

BYTE	eprom[16] = { 
	0x00,
	0x1e,
	0x12,
	0x87,
	0x01,	// region code
	0xff,	// region count
	0x08,	// parental control
	0x00,	// board type
	0x00,	// microclock type
	0x01,	// DAC 
	0x02,	// spdif and audio channels number ( 2 / 6 )
	0x00,	// reserve
	0x00,	// NTSC , PAL = 1
	0x00,
	0x00,
	0x00	// left channel polarity
};

unsigned char SAA7120_NTSC[36] = {
	0x77,0x76,0xa5,0x2a,0x2e,0x2e,				// 5A-5F
	0x00,0x15,0x3f,0x1f,0x7c,0xf0,0x21,0x00,	// 60-67
	0x00,0x00,0x00,0x29,0x02,0x00,0x80,0x00,	// 68-6F
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	// 70-77
	0x00,0x00,0x00,0x00,0x00,0x00				// 78-7D
};

unsigned char SAA7120_PAL[36] = {
	0x77,0x76,0xa5,0x2a,0x2e,0x2e,				// 5A-5F
	0x00,0x16,0x3f,0xcb,0x8a,0x09,0x2a,0x00,	// 60-67
	0x00,0x00,0x00,0x29,0x02,0x00,0x80,0x00,	// 68-6F
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	// 70-77
	0x00,0x00,0x00,0x00,0x00,0x00				// 78-7D
};

unsigned char AD7176_NTSC[19] = {
	0x04,0x00,0x16,0x7c,0xf0,0x21,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00 

};

unsigned char AD7176_PAL[19] = {
	0x05,0x00,0xcb,0x8a,0x09,0x2a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00 
};

unsigned char HS8171_NTSC[] = {
	0x00,0x20,0xa0,0xa1,0x00,0x00,0x00,0x00,0x10,0x80,0x80,0x80,0x80,0x00,0x00,0x00,
	0x00,0x3f,0x3f,0x4a,0x03,0x7a,0x03,0x01,0x13,0x80,0x00
};

unsigned char HS8171_PAL[] = {
	0x40,0x20,0xa0,0xa1,0x00,0x00,0x00,0x00,0x10,0x80,0x80,0x80,0x80,0x00,0x00,0x00,
	0x00,0x3f,0x3f,0x5e,0x03,0x8e,0x36,0x01,0x16,0x80,0x00
};

DWORD	gamma[][8] = {
	{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
	{0x0,0x0,0x1000000,0x05040302,0x07070606,0x0b0a0908,0x0b0c0b0b,0xe0e0d},
	{0x0,0x03020200,0x07060505,0x0a090808,0x0b0b0b0a,0x0d0d0c0c,0x0e0e0e0d,0x010f0f0f}, 
	{0x03000000,0x09080706,0x0c0b0b0b,0x0e0e0d0d,0x0f0f0f0f,0x10100f0f,0x1010100f,0x010f1010}, 
	{0x08050100,0x0e0d0d0b,0x11101010,0x12121112,0x12121212,0x12121212,0x11111111,0x020f1011}, 
	{0x0d0a0500,0x13121210,0x15151515,0x16161616,0x15151616,0x14141415,0x12131313,0x020f1112}, 
	{0x120e0900,0x18171615,0x19191919,0x1919191a,0x17181919,0x16161617,0x13141415,0x020f1212}, 
	{0x16130d00,0x1c1c1b19,0x1d1d1d1e,0x1d1d1d1e,0x1a1b1c1c,0x1818191a,0x14151616,0x020f1213}, 
	{0x1b171000,0x21201f1e,0x21212122,0x20202021,0x1c1d1e1f,0x191a1a1c,0x15161718,0x020f1314}, 
	{0x1f1b1400,0x24242322,0x24252525,0x22232324,0x1e1f2121,0x1b1c1c1e,0x16171819,0x020f1315} 
};

DWORD	chroma_U[][7] = {
	{0x2,0x0,0x0,0x0,0x0,0x0,0x0},
	{0x3f3f3f02,0x3f3f3f3f,0x0,0x0,0x0,0x01010100,0x02020201},
	{0x3e3d3d02,0x3e3e3e3e,0x3f3f3f3f,0x0,0x01000000,0x03020201,0x04040403},
	{0x3c3c3b02,0x3d3d3d3c,0x3f3e3e3e,0x3f3f,0x02010000,0x04040302,0x07060605},
	{0x3b3a3a02,0x3c3c3c3b,0x3e3e3d3d,0x3f3f,0x02010000,0x06050403,0x09080807},
	{0x39393a02,0x3b3b3a3a,0x3e3d3d3c,0x3f3f3e,0x03020100,0x07060504,0x0c0b0a08},
	{0x38373a02,0x3a3a3938,0x3d3c3c3b,0x3f3e3e,0x04020100,0x09080605,0x0e0d0c0a},
	{0x36363a02,0x39393837,0x3d3c3b3a,0x3f3e3d,0x04030100,0x0a090706,0x100f0e0c},
	{0x35343a02,0x38383736,0x3c3b3a39,0x3f3e3d,0x05030100,0x0c0a0807,0x1011100e},
	{0x33323a02,0x37363534,0x3b3a3938,0x3f3e3d3c,0x06040200,0x0e0c0a08,0x10141210}
};

DWORD	chroma_V[][7] = {
	{0x023a0202,0x02020202,0x02020202,0x02020202,0x02020202,0x02020202,0x02020202},
	{0x380002,0x0,0x01010101,0x02020101,0x03030202,0x04040303,0x05050404},
	{0x3f3e3e07,0x3f3f,0x01000000,0x02020101,0x04040302,0x06060505,0x08080707},
	{0x3d3c3c0a,0x3f3e3e3d,0x3f,0x02020101,0x06050403,0x09080706,0x0c0b0a0a},
	{0x3b3a3a0a,0x3e3d3c3c,0x3f3e,0x02020100,0x07060503,0x0b0a0908,0x0f0e0d0c},
	{0x39383a0a,0x3d3c3b3a,0x3f3e3d,0x02020100,0x08070603,0x0e0c0b0a,0x1012100f},
	{0x373e3a0a,0x3b3a3938,0x3f3e3d3c,0x03020100,0x0a080604,0x100e0d0b,0x10151312},
	{0x363c3a0a,0x3a393837,0x3f3e3d3b,0x03020000,0x0b090704,0x12100f0d,0x10181614},
	{0x343a3a0a,0x39383635,0x3e3d3c3a,0x03020000,0x0c0a0804,0x1513100e,0x10181917},
	{0x323a3a0a,0x38363533,0x3e3c3b39,0x0302003f,0x0e0b0905,0x17151210,0x10181c1a}
};

BYTE	ebuf[128] = {0};


extern DWORD BASE;
extern BOOL m_spdif_first_play;
extern BOOL ac3_flag;

//function declarations

#ifdef DBG
	extern ULONG DbgPrint(PCH pchFormat, ...);
#endif
extern DWORD GetDWORD(unsigned char *p);
extern VOID KeStallExecutionProcessor(IN ULONG MicroSeconds);
extern void Wait();

/////////////////////////////////////////////////////////////////////////////////

DWORD DDiv(DWORD a, DWORD b, DWORD dv)
{
#ifdef HW_ASM
WORD wlo=0, whi=0;
_asm {
	cmp     dv,0
	je      Error
	push	eax
	push	ebx
	push	edx

	mov     eax,a
	mov     ebx,b
	imul    ebx
	mov     ebx,dv
	idiv    ebx
	shld    edx,eax,16
	mov		whi,dx
	mov		wlo,ax

	pop	edx
	pop	ebx
	pop	eax
Error:
	}

	return MAKELONG(wlo,whi);
#else
/*
LARGE_INTEGER num;
LARGE_INTEGER result;
	
	num = RtlConvertUlongToLargeInteger((ULONG)(a*b));
	result = RtlExtendedLargeIntegerDivide(num,dv,NULL);

	return (DWORD)(result.LowPart);
*/

	return (DWORD)( (a*b)/dv );
#endif
}

/////////////////////////////////////////////////////////////////////////////////

void LUXInit(DWORD base)
{
	#ifdef DBG
		if(base != 0)
			DbgPrint("luxdvd : LUXInit with base = 0x%lx\n",base);
		else
			DbgPrint("luxdvd : Inside LUXInit\n");
	#endif

	if( base != 0 )	
		luxbase = base;

	LUXVideoVarInit();
	LUXAudioVarInit();

	LUXVideoResetChip();

	if ( detect_i2c(0xa0) )
	{
		#ifdef DBG
			DbgPrint("luxdvd : detected EPROM\n");
		#endif

		i2c_readeprom(0xa0,0,16,eprom);

		if ( !v_m_VideoSrc_NTSC )	// PAL
			eprom[EPROM_TVOUT] = 1;

		m_eprom = TRUE;
		if (eprom[EPROM_BOARDTYPE] == 1)
		{
			send_gpio(6,5);		// set Chrontel
			send_gpio(3,0xf);
		}
	}
	else
	{
		#ifdef DBG
			DbgPrint("luxdvd : no EPROM\n");
		#endif
		m_eprom = FALSE;	// no eprom , get TV out from ini file
		eprom[EPROM_TVOUT] = 0;	// NTSC
	}

	LoadUcode(1);	// 1 means AC3 by default
	
	LUXAudioSetAudioInfo();	// clock chip definition , etc

	//Originally SPDIF is determined from Win95 Registry
	//Here we do it from the eprom
	
	if ( eprom[EPROM_SPDIF_ONOFF] )
		m_spdif = TRUE;
	else
		m_spdif = FALSE;

	if ( eprom[EPROM_SPDIF_CH]&0x2 || !m_spdif )
	{
		#ifdef DBG
			DbgPrint("luxdvd : no SPDIF\n");
		#endif
		m_spdif_first_play = FALSE;
		LUXAudioSetSPDIF(FALSE);	// no spdif
	}
	else
	{
		#ifdef DBG
			DbgPrint("luxdvd : detected SPDIF\n");
		#endif
		m_spdif_first_play = TRUE;
		LUXAudioSetSPDIF(TRUE);
	}

	LUXVideoResetChip();

	LUXVideoInit(FALSE);

	LUXAudioInit(1);	//AC3 by default
	
	orig_tvout = eprom[EPROM_TVOUT];	// original TV OUT
}

/////////////////////////////////////////////////////////////////////////////////

void LUXChngDSP(int audio_type, int vga_type)
{
	#ifdef DBG
		DbgPrint("luxdvd : LUXChngDSP\n");
	#endif

	LUXVideoVarInit();
	LUXAudioVarInit();

	LUXVideoResetChip();

	LUXVideoSetVPM(1,vga_type);
		
	if ( detect_i2c(0xa0) )
	{
		#ifdef DBG
			DbgPrint("luxdvd : detected EPROM\n");
		#endif
		i2c_readeprom(0xa0,0,16,eprom);
		m_eprom = TRUE;
		if (eprom[EPROM_BOARDTYPE] == 1)
		{
			send_gpio(6,5);		// set Chrontel
			send_gpio(3,0xf);
		}
	}
	else
	{
		#ifdef DBG
			DbgPrint("luxdvd : no EPROM\n");
		#endif
		m_eprom = FALSE;	// no eprom , get TV out from ini file
		eprom[EPROM_TVOUT] = 0;	// NTSC
		//eprom[EPROM_TVOUT] = 1;	// PAL
	}

	if ( v_m_VideoSrc_NTSC )	// NTSC Source
		eprom[EPROM_TVOUT] = 0;	// NTSC Source set to NTSC Output
	else
		eprom[EPROM_TVOUT] = 1;	// PAL source force to PAL output
	
	#ifdef DBG
		DbgPrint("luxdvd : load new dsp code\n");
	#endif

	LoadUcode((BYTE)audio_type);	// 1 means AC3 by default

	LUXAudioSetAudioInfo();	// clock chip definition , etc

	//Originally SPDIF is determined from Win95 Registry
	//Here we do it from the eprom
	if ( eprom[EPROM_SPDIF_ONOFF] )
		m_spdif = TRUE;
	else
		m_spdif = FALSE;

	if ( eprom[EPROM_SPDIF_CH]&0x2 || !m_spdif )
	{
		#ifdef DBG
			DbgPrint("luxdvd : no SPDIF\n");
		#endif
		m_spdif_first_play = FALSE;
		LUXAudioSetSPDIF(FALSE);	// no spdif
	}
	else
	{
		#ifdef DBG
			DbgPrint("luxdvd : detected SPDIF\n");
		#endif
		m_spdif_first_play = TRUE;
		LUXAudioSetSPDIF(TRUE);
	}

	LUXVideoResetChip();

	LUXVideoInit(FALSE);
	LUXAudioInit(audio_type);
}
/////////////////////////////////////////////////////////////////////////////////

void LUXVideoVarInit()
{
	#ifdef DBG
		//DbgPrint("luxdvd : LUXVideoVarInit\n");
	#endif
	v_m_zoomin = FALSE;
	v_m_comp	= 1;
	v_m_speed	= 1000;
	v_m_VPM	= 0;
	v_m_Letter= 0;
	v_m_total = 0;
	v_PTS = 0;
	v_wptr = VID_FIFO_OFF;
	v_remainder = 0;
	v_m_PanScan = 0;
	v_m_tvencoder = 0;	// BT865
	v_m_fullscrn	= FALSE;
	v_m_aps	= 0;		// aps mode for MV7

	HW_WRAP_AROUND = 0xf00000;	// default for MPEG2

	#ifndef P2DAUGHTER
	if ( detect_i2c(0xa0) )
	{
		i2c_readeprom(0xa0,0,16,eprom);	// for getting boardtype earlier !!
	}
	#endif
	
	LUXVideoResetChip();
	v_m_tvencoder = detect_i2c_device();
}

/////////////////////////////////////////////////////////////////////////////////

BOOL LUXVideoWritePTS(DWORD pts)
{
DWORD	pRd,pWr,space,dwVal;
	
	pRd = DVReadDRAM(PTS_FIFO_READ);
	pWr = DVReadDRAM(PTS_FIFO_WRITE);
	space = (pWr >= pRd)? (PTS_FIFO_LEN+pRd-pWr):(pRd-pWr);

	if (space < 0x8)	 //space need to be at least 0x10
	{					// MPEG1 stop then play , it will hang here if the
		return FALSE;	// checking is <= 8 
	}

	if( !v_PTS) 
	{
		DVWriteREG(SYNC_STC,(pts<<1)-0x400);
		dwVal = DVReadDRAM(SYNC_VID_CONTROL);	
		DVWriteREG(SYNC_VID_CONTROL,dwVal|0x28L);	// enable PTS
		DVWriteDRAM(0x250,(pts<<1)+0x500);
		DVWriteREG(SYNC_VID_CONTROL,DVReadReg(SYNC_VID_CONTROL)&0xffffffdfL);
	}

#ifndef LS240
	if ( ( v_m_total & HW_WRAP_AROUND ) == HW_WRAP_AROUND )	// When Bytes count is about to wrap around ( REG 1a4 , only 24bits )
		return TRUE;										// can't send PTS and bytes count to PTS FIFO. Otherwise , HW will confuse !!

		
	if ( ( v_m_total & 0xc00000 ) == 0 )
	{
		if ( ( DVReadReg(0x1a4) & 0xc00000 ) == 0xc00000 ) 
			return TRUE;
	}
#endif

	DVWriteDRAM(DRAM_BASE+pWr,pts);	
	pWr += 4;
	DVWriteDRAM(DRAM_BASE+pWr,v_m_total<<1);
	pWr += 4;
	
	if (pWr >= (PTS_FIFO_OFF+PTS_FIFO_LEN))
		pWr -= PTS_FIFO_LEN;

	DVWriteREG(PTS_FIFO_WRITE,pWr);

	v_PTS = pts;
	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////////

DWORD LUXSendData(BYTE *pdata, BYTE *p, DWORD dwsize, DWORD pts, BOOL b_scr)
{
DWORD	dstoff;
DWORD	srcoff;
DWORD	hwspace,size;
DWORD	len = dwsize;
DWORD	off=0;
DWORD	tmpdw;
int		i=0;

	m_noVideo = 0;

	//pdata is the full packet, p is the video data only

	if ((VID_FIFO_LEN-DVReadDRAM(MPGVID_FIFO_BYTES))<(0x3000))//hw has space
	{
		return 0;
	}

	if(pts && (v_m_speed==1000))
	{
		if( !LUXVideoWritePTS(pts) )
		{
			#ifdef DBG
				DbgPrint("luxdvd ERROR : LUXVideoWritePTS failed !!!!\n");
			#endif
			return 0;
		}
	}

	srcoff  = (DWORD)(p);
	dstoff	= DRAM_BASE + v_wptr;
	hwspace	= VID_FIFO_LEN+VID_FIFO_OFF - v_wptr;
	
	if(b_scr)	//do descrambling
	{
		off = v_wptr + pdata + 80 - p;
		if (off >= (VID_FIFO_OFF+VID_FIFO_LEN))
			off -= VID_FIFO_LEN;
		DVWriteREG(0x24,off|0x400000L);

		#ifdef LS240
			dstoff = v_wptr;
		#endif
	}
	    
	if ( (unsigned)hwspace >= len)
    {               // check circle
        DVMoveStr(dstoff,srcoff,len);
	} 
	else 
	{
		DVMoveStr(dstoff,srcoff,hwspace);
		dstoff = DRAM_BASE + VID_FIFO_OFF;
		#ifdef LS240
			if(b_scr)
			{
				dstoff = VID_FIFO_OFF;
			}
		#endif
		DVMoveStr(dstoff,(DWORD)(srcoff+hwspace),(len-hwspace));
	}

	DVWriteREG(0x24,0L);
    
	v_wptr += len;
	if (v_wptr >= (VID_FIFO_OFF+VID_FIFO_LEN))
		v_wptr -= (VID_FIFO_LEN);
		
	v_m_total += len;		// update the real length first

	len += v_remainder;
	v_remainder = (WORD)len & 0x3f;

	DVWriteREG(MPGVID_FIFO_ADDBLOCK,len&0xfffc0);

#ifndef LS240
#ifndef LS220E
	if ( isStillMenu && !v_m_mpeg1)
	{
		tmpdw = DVReadDRAM(MPGVID_CONTROL); // stop run to read Qtable
		DVWriteREG(MPGVID_CONTROL,tmpdw & (~0x4));
		for(i=0;i<20;i++) 
		{
			if ( !(DVReadDRAM(0x1b4)&0x1)) 
				break;
		}

 		if ( DVReadDRAM(0x145fc) == 0x1 ) 
		{
			if ( DVReadDRAM(0x145f8) == 0x1 )
				DVWriteDRAM(0x145fc,0x2);
		}

		DVWriteREG(MPGVID_CONTROL,tmpdw);
	}
#endif
#endif

	return dwsize;
}

/////////////////////////////////////////////////////////////////////////////////

void LUXVideoSetXY(WORD x,WORD y)
{
	#ifdef DBG
		//DbgPrint("luxdvd : LUXVideoSetXY()\n");
	#endif

	if ( (x == width) && (y == height) )
		return;

	LUXVideoCleanScreen();

	width = x & 0xfff0;
	height = y & 0xfff0;

	if ( !v_m_mpeg1 )	// MPEG2
	{
		if ( y > 480 )
		{
			#ifdef DBG
				DbgPrint("luxdvd : LUXVideoSetXY() - PAL SOURCE !\n");
			#endif
			v_m_VideoSrc_NTSC = FALSE;	// PAL Source
			v_m_frame_period = 0x7080e10;
		}
		else	
		{
			v_m_VideoSrc_NTSC = TRUE;	// NTSC Source
			v_m_frame_period = 0x5940bb8;
		}

		DVWriteREG(SYNC_FRAME_PERIOD,v_m_frame_period);
	}
	else	// MPEG1
	{
		if ( y >= 480 )	// Hi-Res
		{
			if ( y != 480 )
				v_m_VideoSrc_NTSC = FALSE;	// PAL Source
			else	
				v_m_VideoSrc_NTSC = TRUE;	// NTSC Source
		}
		else
		{
			if ( y > 240 )
				v_m_VideoSrc_NTSC = FALSE;	// PAL Source
			else	
				v_m_VideoSrc_NTSC = TRUE;	// NTSC Source
		}
	}

	if ( !v_m_mpeg1 )	// Monitor Only
	{
		if ( v_m_VideoSrc_NTSC )	// NTSC Source
			eprom[EPROM_TVOUT] = orig_tvout;	// NTSC Source set to whatever output from eeprom
		else
			eprom[EPROM_TVOUT] = 1;	// PAL source force to PAL output
	}
	else	// MPEG1 
	{
		eprom[EPROM_TVOUT] = orig_tvout;
	}

	DVWriteREG(0x328,DDiv(x,0x800L,720));	

	if (!eprom[EPROM_TVOUT])	// NTSC output
	{
		if ( !v_m_mpeg1 )
		{
			DVWriteREG(0x32c,DDiv(y,0x400L,480));	
			DVWriteDRAM(DSPMEM_LOCK,DDiv(y,0x400L,480));
		}
		else	// VCD
		{
			if ( y >= 480 )	// HI-RES
			{
				DVWriteREG(0x32c,DDiv(y,0x400L,480));	
				DVWriteDRAM(DSPMEM_LOCK,DDiv(y,0x400L,480));
			}
			else	// LOW-RES
			{
				if ( v_m_VideoSrc_NTSC )	// NTSC Source
				{
					DVWriteREG(0x32c,0x200);
					DVWriteDRAM(DSPMEM_LOCK,0x200);
				}
				else					// PAL SOURCE
				{
					DVWriteREG(0x32c,0x280);
					DVWriteDRAM(DSPMEM_LOCK,0x280);
				}
			}
		}
	}
	else	// PAL output
	{
		if ( !v_m_mpeg1 )
		{
			DVWriteREG(0x32c,DDiv(y,0x355L,480)+1);	
			DVWriteDRAM(DSPMEM_LOCK,DDiv(y,0x355L,480)+1);
		}
		else	// VCD
		{
			if ( y >= 480 )
			{
				DVWriteREG(0x30c,0x1370014);	
				//DVWriteREG(0x32c,DDiv(y,0x390L,480)+1);	// got this 0x390 by trying on ATI VGA
				//DVWriteDRAM(DSPMEM_LOCK,DDiv(y,0x390L,480)+1);
				DVWriteREG(0x32c,DDiv(y,0x374L,480)+1);	// got this 0x390 by trying on ATI VGA
				DVWriteDRAM(DSPMEM_LOCK,DDiv(y,0x374L,480)+1);
			}
			else
			{

				DVWriteREG(0x30c,0x1350014);	
				
				if(v_m_VideoSrc_NTSC)
				{
					DVWriteREG(0x32c,0x1b5);
					DVWriteDRAM(DSPMEM_LOCK,0x1b5);
				}
				else	//PAL
				{
					DVWriteREG(0x32c,0x200);
					DVWriteDRAM(DSPMEM_LOCK,0x200);
				}
			}
		}
	}

	DVWriteREG(MPGVID_MB_WIDTH,x>>4);
	DVWriteREG(MPGVID_MB_HEIGHT,y>>4);

	if( v_m_mpeg1 ) 
	{
		DVWriteREG(MPGVID_SETUP,0x3fc);
	}
	else
	{	// MPEG-2: 720x480
		if ( !v_m_VideoSrc_NTSC )
		{
			DVWriteREG(MPGVID_MB_WIDTH,0x222d);	// PAL Src , B-frame comp
			#ifdef LINE21
				DVWriteREG(MPGVID_SETUP,0x403f5|0x2);	// PAL Mapping , bit 18
			#else
				DVWriteREG(MPGVID_SETUP,0x403f5);	// PAL Mapping , bit 18
			#endif
		}
		else
		{
			DVWriteREG(MPGVID_MB_WIDTH,0x2d);	// NTSC Src , No B-frame comp
			#ifdef LINE21
				DVWriteREG(MPGVID_SETUP,0x3f4|0x2);
			#else
				DVWriteREG(MPGVID_SETUP,0x3f4);
			#endif
		}
	}

}

/////////////////////////////////////////////////////////////////////////////////

void LUXVideoSetVideo()
{
	#ifdef DBG
		//DbgPrint("luxdvd : LUXVideoSetVideo\n");
	#endif

	LUXVideoReset();

	#ifdef CHANGE_REG274 // Odd/Even Field
		LUXVideoSetVPM(v_m_VPM,v_m_vga);
	#endif
		
	#ifdef LS240
		DVWriteREG(0x300,0x12c5);	//
		DVWriteREG(0x37c,0x14L);	//
	#endif

	DVWriteREG(0x310,0x8080L);	//

	DVWriteREG(0x328,DDiv(width,0x800L,720));	//

	if (!eprom[EPROM_TVOUT])
	{
		DVWriteREG(0x32c,DDiv(height,0x400L,480));	//
		DVWriteDRAM(DSPMEM_LOCK,DDiv(height,0x400L,480));
	}
	else
	{
		DVWriteREG(0x32c,DDiv(height,0x355L,480)+1);	//
		DVWriteDRAM(DSPMEM_LOCK,DDiv(height,0x355L,480)+1);
	}

	DVWriteREG(SYNC_FRAME_PERIOD,v_m_frame_period);

	#ifdef QUICKTERM
		DVWriteREG(SYNC_WAIT_LINE,0x3);		// setting for quickterm
	#else
		DVWriteREG(SYNC_WAIT_LINE,0);
	#endif

	#ifdef	LS240
		DVWriteREG(0x200,0x458);	
	#else
		DVWriteREG(0x200,0x58);
	#endif

	DVWriteREG(MPGVID_CONTROL,1);	// reset pointers

	DVWriteREG(MPGVID_MB_WIDTH,width>>4);
	DVWriteREG(MPGVID_MB_HEIGHT,height>>4);
	if (v_m_mpeg1)
	{	// MPEG-1: 352x240
		DVWriteREG(MPGVID_SETUP,0x3fc);
		DVWriteREG(0x324,0x4);	//
	}
	else
	{	// MPEG-2: 720x480

		if ( !v_m_VideoSrc_NTSC )
		{
			DVWriteREG(MPGVID_MB_WIDTH,0x222d);	// PAL Src , B-frame comp
			#ifdef LINE21
				DVWriteREG(MPGVID_SETUP,0x403f5|0x2);	// PAL Mapping , bit 18
			#else
				DVWriteREG(MPGVID_SETUP,0x403f5);	// PAL Mapping , bit 18
			#endif
		}
		else
		{
			DVWriteREG(MPGVID_MB_WIDTH,0x2d);	// NTSC Src , No B-frame comp
			#ifdef LINE21
				DVWriteREG(MPGVID_SETUP,0x3f4|0x2);
			#else
				DVWriteREG(MPGVID_SETUP,0x3f4);
			#endif
		}

		#ifndef DO_NOT_TOUCH_REG324
			if( DVReadReg(0x32c) != 0x400 )
				DVWriteREG(0x324,0x0);	//
			else
				DVWriteREG(0x324,0xf);	//
		#endif
	}

	if( v_m_vga == CCIR656_VGA )
		DVWriteREG(0x304,0x620b000aL);	//
	else
		DVWriteREG(0x304,0x220b000aL);	//


#ifndef LS240
	#ifndef LINE21
		DVWriteREG(SYNC_INT_CTRL,0x88000);
	#else
		DVWriteREG(SYNC_INT_CTRL,0x88000 | 0x100);
	#endif
#endif

#ifndef LS240
	#ifdef QUICKTERM
		DVWriteREG(0x80,0x700ab33e);
	#else
		DVWriteREG(0x80,0x300a33bdL);	//
	#endif
#endif

	DVWriteREG(0x24,0);	// clear scramble

// ----------------------------

	//pgm the dsp run ctrl reg

	DVWriteREG(0x104,0x0);		// dsp stop
	DVWriteREG(0x100,0x7c600L);
	DVWriteREG(0x104,0x1);		// dsp run

	#ifdef LINE21
		DVWriteREG(0x20,0x104);	//vid line reached interrupt and dsp irq
	#else
		DVWriteREG(0x20,0x104);	//vid line reached interrupt
	#endif

	KeStallExecutionProcessor(50);

	LUXVideoSetMode();

	#ifdef CHANGE_REG274
		DVWriteREG(0x274,DVReadReg(0x274)|0x8000);
	#endif

}

/////////////////////////////////////////////////////////////////////////////////

void LUXVideoResetChip()
{
	#ifdef DBG
		//DbgPrint("luxdvd : LUXVideoResetChip\n");
	#endif

#ifdef	LS240
	DVWriteREG(0x10,1);
	DVWriteREG(0x10,0x30);
	
	DVWriteREG(0x300,0x0);
	
	DVWriteREG(0x84,0x04400000L);	//
	KeStallExecutionProcessor(10);
	DVWriteREG(0x80,0x66a428ecL);	//
	KeStallExecutionProcessor(10);
	DVWriteREG(0x84,0x80400000L);	//

	DVWriteREG(0x300,0x12c5);
#else
	DVWriteREG(0x10,1);	// reset chip
	DVWriteREG(0x10,0);	//
#endif
	
	iic_init();
}

/////////////////////////////////////////////////////////////////////////////////

void LUXVideoInit(BOOL mpeg1)
{
	#ifdef DBG
		//DbgPrint("luxdvd : LUXVideoInit\n");
	#endif

	v_m_mpeg1 = mpeg1;

	if ( v_m_mpeg1 )
		HW_WRAP_AROUND = 0xffc000;
	else
		HW_WRAP_AROUND = 0xf00000;

	LUXVideoSetVideo();
	LUXVideoCleanScreen();
	LUXVideoSetGamma(1);	//ms dvdplay does not have feature to alter gamma
}

/////////////////////////////////////////////////////////////////////////////////

void LUXVideoCleanScreen()
{
	#ifdef DBG
		//DbgPrint("luxdvd : LUXVideoCleanScreen\n");
	#endif
	
	DVWriteREG(0x3d0,0);	//clean subpic

	//if (!eprom[EPROM_TVOUT]) 
	if(v_m_VideoSrc_NTSC || v_m_mpeg1) // NTSC 
	{
		DVStoreStr(0x200000L,0x0L,0x54600L);
		DVStoreStr(0x254600L,0x80808080L,0x2a300L);
		DVStoreStr(0x27e900L,0x0L,0x54600L);
		DVStoreStr(0x2d2f00L,0x80808080L,0x2a300L);
		DVStoreStr(0x2fd200L,0x0L,0x54600L);
		DVStoreStr(0x351800L,0x80808080L,0x2a300L);
	}
	else
	{
		DVStoreStr(0x200000L,0x0L,0x65400L);
		DVStoreStr(0x265400L,0x80808080L,0x32a00L);
		DVStoreStr(0x297e00L,0x0L,0x65400L);
		DVStoreStr(0x2fd200L,0x80808080L,0x32a00L);
		DVStoreStr(0x32fc00L,0x0L,0x65400L);
		DVStoreStr(0x395000L,0x80808080L,0x32a00L);
	}
}

/////////////////////////////////////////////////////////////////////////////////

void LUXVideoClose()
{
	#ifdef DBG
		//DbgPrint("LUXVideoClose\n");
	#endif

	#ifndef CHANGE_REG274
		DVWriteREG(0x30c,0x190018L);	// blank screen
	#endif

	LUXVideoCleanScreen();
	v_remainder = 0;

	LUXVideoReset();
}

/////////////////////////////////////////////////////////////////////////////////

void LUXVideoPlayStill()
{
DWORD reg180;

	#ifdef DBG
		//DbgPrint("LUXVideoPlayStill\n");
	#endif

	DVWriteREG(0x200,0x7b);		// set bit 0 to 1

	reg180 = DVReadReg(MPGVID_CONTROL) & 0x1e0;

	DVWriteREG(MPGVID_CONTROL,reg180|0x4);	// start pointers, was 6

	LUXVideoSetVPM(v_m_VPM,v_m_vga);

	LUXVideoSetLetter(v_m_Letter);

#ifdef LS240
	#ifdef LINE21
		DVWriteREG(SYNC_INT_CTRL,0x88004401L | 0x100);
	#else
		DVWriteREG(SYNC_INT_CTRL,0x88004401L);
	#endif
#else
	#ifdef LINE21
		DVWriteREG(SYNC_INT_CTRL,0x224401L | 0x100);	// LINE21
	#else
		DVWriteREG(SYNC_INT_CTRL,0x224401L);
	#endif
#endif

	DVWriteREG(0x278,0x4000);	// force 
}

/////////////////////////////////////////////////////////////////////////////////

void LUXVideoPlay(int speed)
{
DWORD dwval=0;
DWORD reg180;
	
	//We may have paused in either slow motion playback or 2X
	//in which case, we would have stopped the STC
	//Hence here we must re-enable the STC thru reg 0x200
	//Note that if we are in normal playback, we use host control sync
	//and the state of the STC is not relevant

#ifndef LS240
#ifndef LS220E
	if ( isStillMenu && !v_m_mpeg1) 
	{
		if (DVReadDRAM(0x145fc) == 0x1)
			DVWriteDRAM(0x145fc,0x2);
	}
#endif
#endif

#ifdef CHANGE_REG274	// Odd/Even Field
	if ( (v_m_VideoSrc_NTSC && eprom[EPROM_TVOUT] )	// NTSC SRC , but PAL output 
		|| (!v_m_VideoSrc_NTSC && !eprom[EPROM_TVOUT] ) ) // PAL SRC , But NTSC output
	{
		DVWriteREG(0x268,DVReadReg(0x268)|0x80);
	}

	DVWriteREG(0x268,DVReadReg(0x268)&0xa0);
#endif

	dwval = DVReadDRAM(0x200);
	DVWriteREG(0x200,(DWORD)(dwval|0x1));	//set bit 0 to 1

	reg180 = DVReadReg(MPGVID_CONTROL) & 0x1e0;

#ifdef CHANGE_MPGVID_CONTROL
	DVWriteREG(MPGVID_CONTROL,reg180|0x6);	// start pointers, was 6
#else
	DVWriteREG(MPGVID_CONTROL,reg180|0x4);	// start pointers, was 6
#endif

#ifndef CHANGE_REG274	// Odd/Even Field
	LUXVideoSetVPM(v_m_VPM,v_m_vga);
#endif

	if(!v_m_zoomin)
		LUXVideoSetLetter(v_m_Letter);

	#ifdef	LS240
		if ( v_m_zoomin )
		{
			#ifdef LINE21
				DVWriteREG(SYNC_INT_CTRL,0xc8000001L | 0x100);
			#else
				DVWriteREG(SYNC_INT_CTRL,0xc8000001L);
			#endif
		}
		else
		{
			#ifdef LINE21
				DVWriteREG(SYNC_INT_CTRL,0x38000001L | 0x100);
			#else
				DVWriteREG(SYNC_INT_CTRL,0x38000001L);
			#endif
		}
	#else
		#ifdef CHANGE_REG274
			if ( v_m_zoomin )
			{
				#ifdef LINE21
					DVWriteREG(0x274,0x328001 | 0x100);	// zoom in , force MPEG decode early
				#else
					DVWriteREG(0x274,0x328001);	// zoom in , force MPEG decode early
				#endif
			}
			else
			{
				#ifdef LINE21
					DVWriteREG(SYNC_INT_CTRL,0xe8001L | 0x100);
				#else
					DVWriteREG(SYNC_INT_CTRL,0xe8001L);
				#endif
			}
		#else
			#ifdef LINE21
				DVWriteREG(SYNC_INT_CTRL,0xe0001L | 0x100);
			#else
				DVWriteREG(SYNC_INT_CTRL,0xe0001L);
			#endif
		#endif
	#endif

	LUXVideoSetSpeed(speed);

}

/////////////////////////////////////////////////////////////////////////////////

void LUXVideoStop()
{
DWORD dwval;
DWORD reg180;
	
	#ifdef DBG
		//DbgPrint("luxdvd : LUXVideoStop\n");
	#endif

	dwval = DVReadDRAM(SYNC_INT_CTRL);

	#ifdef LS240
		#ifdef LINE21
			DVWriteREG(SYNC_INT_CTRL,(dwval&0xfffffffeL) | 0x100);	
		#else
			DVWriteREG(SYNC_INT_CTRL,dwval&0xfffffffeL);	
		#endif
	#else
		#ifdef LINE21
			DVWriteREG(SYNC_INT_CTRL,(dwval&0xfffffeL) | 0x100);	
		#else
			DVWriteREG(SYNC_INT_CTRL,dwval&0xfffffeL);	
		#endif
	#endif
	
	dwval = DVReadDRAM(0x200);
	DVWriteREG(0x200,(DWORD)(dwval & 0xfffe));	// stop STC
	
	reg180 = DVReadReg(MPGVID_CONTROL) & 0x1e0;
	DVWriteREG(MPGVID_CONTROL,reg180|0x0);

	DVWriteREG(0x194,VID_FIFO_OFF);
	v_m_total = 0;
	v_remainder = 0;
	v_wptr = VID_FIFO_OFF;

	v_PTS = 0;

	reg180 = DVReadReg(MPGVID_CONTROL) & 0x1e0;
	DVWriteREG(MPGVID_CONTROL,reg180|0x1);

}

/////////////////////////////////////////////////////////////////////////////////

void LUXVideoPause()
{
DWORD dwval = 0;

	#ifdef DBG
		//DbgPrint("luxdvd : LUXVideoPause\n");
	#endif

	if(v_m_speed == 1000)	//normal playback
	{
	}
	else	
	{
		DVWriteREG(0x19c,0x2);	
	}	

//  For MicroSoft , They don't want STC to stop while Pause
/*
	//For either slow motion or 2X, we must stop the STC from running
	//This has no efffect on host controled sync as it doesn't use STC
	dwval = DVReadDRAM(0x200);
	DVWriteREG(0x200,(DWORD)(dwval & 0xfffe));	//set bit 0 of reg 0x200 to 0 to stop STC
*/

#ifdef CHANGE_REG274
	#ifdef LINE21
		DVWriteREG(SYNC_INT_CTRL,0x28000L | 0x100); 	// LINE21
	#else
		DVWriteREG(SYNC_INT_CTRL,0x28000L);
	#endif
#else
	#ifdef LINE21
		DVWriteREG(SYNC_INT_CTRL,0x88000000L | 0x100);	// LINE21
	#else
		DVWriteREG(SYNC_INT_CTRL,0x88000000L);
	#endif
#endif
}

/////////////////////////////////////////////////////////////////////////////////

DWORD LUXVideoGet_STC()
{
	return DVReadReg(0x218);
}

/////////////////////////////////////////////////////////////////////////////////

void LUXVideoFFward()
{
DWORD dwVal;

	#ifdef DBG
		//DbgPrint("luxdvd : LUXVideoFFward\n");
	#endif
	
#ifdef LS240
	v_m_speed = 2000;
	#ifdef LINE21
		DVWriteREG(0x274,0x28000001|0x100);
	#else
		DVWriteREG(0x274,0x28000001);
	#endif
	DVWriteREG(0x268,(DVReadReg(0x268)&0xa0)|0x1);
#else

	#ifdef CHANGE_REG274
		v_m_speed = 2000;
		#ifdef LINE21
			DVWriteREG(0x274,0xa8001 | 0x100);	// LINE21
		#else
			DVWriteREG(0x274,0xa8001);
		#endif
		DVWriteREG(0x268,(DVReadReg(0x268)&0x20)|0x1);
	#else
		#ifdef LINE21
			DVWriteREG(0x274,0xa0001 | 0x100);	// LINE21
		#else
			DVWriteREG(0x274,0xa0001);
		#endif
	#endif

#endif
}

/////////////////////////////////////////////////////////////////////////////////

void LUXVideoContinue()
{
	LUXVideoPlay(v_m_speed);
}

/////////////////////////////////////////////////////////////////////////////////

void LUXVideoReset()
{
	#ifdef DBG
		//DbgPrint("luxdvd : LUXVideoReset\n");
	#endif

	DVWriteREG(MPGVID_CONTROL,0);

	KeStallExecutionProcessor(20);

	DVWriteREG(MPGVID_FIFO_START,VID_FIFO_OFF);
	DVWriteREG(MPGVID_FIFO_END,VID_FIFO_OFF+VID_FIFO_LEN);

	DVWriteREG(MPGVID_CONTROL,1);

	DVWriteREG(PTS_FIFO_START,PTS_FIFO_OFF);	
	DVWriteREG(PTS_FIFO_END,PTS_FIFO_OFF+PTS_FIFO_LEN-8);

	DVWriteREG(PTS_FIFO_WRITE,PTS_FIFO_OFF);

	KeStallExecutionProcessor(20);

	v_wptr = VID_FIFO_OFF;

	DVStoreStr(v_wptr+0x200000L,0x0,128);
	v_wptr += 128;
	v_m_total = 128;
	v_remainder = 0;

	DVWriteREG(SYNC_VID_CONTROL,0x22);
	DVWriteREG(SYNC_VID_CONTROL,0x0);

	DVWriteREG(SYNC_VID_CONTROL,0x80000);
	v_PTS = 0;

	DVWriteREG(SYNC_VID_CONTROL,0x0f);

	#ifndef CHANGE_MPGVID_CONTROL
		DVWriteREG(MPGVID_CONTROL,6);
	#endif

}

/////////////////////////////////////////////////////////////////////////////////

void LUXVideoAfterSeek()
{
DWORD dwVal;
DWORD reg180;

	#ifdef DBG
		//DbgPrint("luxdvd : LUXVideoAfterSeek\n");
	#endif

	LUXVideoReset();

	reg180 = DVReadReg(MPGVID_CONTROL) & 0x1e0;

	#ifdef CHANGE_MPGVID_CONTROL
		DVWriteREG(MPGVID_CONTROL,reg180|0x16);	// seek to I-Frame
	#else
		DVWriteREG(MPGVID_CONTROL,reg180|0x14);	// seek to I-Frame
	#endif
}

/////////////////////////////////////////////////////////////////////////////////

void LUXVideoSetLetter(BYTE onoff)
{

}

/////////////////////////////////////////////////////////////////////////////////

void LUXVideoSetMV7(BYTE mode)		// set MacroVision 7 APS mode support
{
	#ifdef DBG
		//DbgPrint("luxdvd : LUXVideoSetMV7\n");
	#endif

	v_m_aps = mode;

	if ( !eprom[EPROM_TVOUT] )
		set_macrovision(v_m_tvencoder,NTSC_VIDEO,mode);
	else
		set_macrovision(v_m_tvencoder,PAL_VIDEO,mode);
}

/////////////////////////////////////////////////////////////////////////////////

void LUXVideoSetMode()
{
BYTE addr;
char *p;
int	i;

	switch (v_m_tvencoder) 
	{
		case BT865: // BT865
		case BT864:
			if (!eprom[EPROM_TVOUT]) 
				send_i2c(0x8a,0xcc,0x0);	// NTSC, 0x8 for NTSC/HDTV
			else
				send_i2c(0x8a,0xcc,0x24);	// PAL

			send_i2c(0x8a,0xce,0x2);	// S-VIDEO and COMP
			send_i2c(0x8a,0xc6,0x2);
			send_i2c(0x8a,0xc8,0x3);
			send_i2c(0x8a,0xca,0x10);
			break;
	
		case SAA7120:	
		case SAA7121:
			send_i2c(0x8c,0x3a,0x3);	
			if (!eprom[EPROM_TVOUT]) 
			{
				send_i2c(0x8c,0x28,0x1a);	
				send_i2c(0x8c,0x29,0x26);	
				p = SAA7120_NTSC;
			} 
			else 
			{
				send_i2c(0x8c,0x28,0x21);	
				KeStallExecutionProcessor(100);
				send_i2c(0x8c,0x29,0x1d);	
				p = SAA7120_PAL;
			}
			for(i=0;i<36;i++)
			{
				KeStallExecutionProcessor(100);
				send_i2c(0x8c,(BYTE)(0x5a+i),p[i]);	// NTSC, 0x8 for NTSC/HDTV
			}
			break;

		case AD7175:
		case AD7176:
			if (v_m_tvencoder == AD7175)
				addr = 0xd4;
			else
				addr = 0x54;
			if (!eprom[EPROM_TVOUT]) 
				p = AD7176_NTSC;
			else 
				p = AD7176_PAL;

			for(i=0;i<19;i++)
				send_i2c(addr,(BYTE)i,p[i]);	// NTSC, 0x8 for NTSC/HDTV
			break;

		case CS4952:
		case CS4953:
			if (!eprom[EPROM_TVOUT]) 
			{
				send_i2c(0x80,0x00,0x03);
				send_i2c(0x80,0x01,0x04);
				send_i2c(0x80,0x04,0x0F);
				send_i2c(0x80,0x10,0x1C);
				send_i2c(0x80,0x11,0x3E);
				send_i2c(0x80,0x12,0xF8);
				send_i2c(0x80,0x13,0xE0);
				send_i2c(0x80,0x14,0x43);
			} 
			else 
			{
				send_i2c(0x80,0x00,0x43);
				send_i2c(0x80,0x01,0x04);
				send_i2c(0x80,0x04,0x0F);
				send_i2c(0x80,0x10,0x15);
				send_i2c(0x80,0x11,0x96);
				send_i2c(0x80,0x12,0x15);
				send_i2c(0x80,0x13,0x13);
				send_i2c(0x80,0x14,0x54);
			}
			break;

		case HS8171:
		case HS8170:
			addr = 0x42;
			if (!eprom[EPROM_TVOUT]) 
				p = HS8171_NTSC;
			else 
				p = HS8171_PAL;

			for(i=1;i<8;i++)
				send_i2c(addr,(BYTE)i,*p++);	// NTSC, 0x8 for NTSC/HDTV
			for(i=0xe;i<0x1a;i++)
				send_i2c(addr,(BYTE)i,*p++);	// NTSC, 0x8 for NTSC/HDTV
			for(i=0x20;i<0x28;i++)
				send_i2c(addr,(BYTE)i,*p++);	// NTSC, 0x8 for NTSC/HDTV
			break;
	}

}

/////////////////////////////////////////////////////////////////////////////////

void LUXVideoSetSpeed(int speed)
{
DWORD dw210 = 0;
DWORD dw214 = 0;
DWORD dwval = DVReadDRAM(0x200);
DWORD dwcount=0;
		
	if(speed != v_m_speed)
	{
		DVWriteREG(PTS_FIFO_WRITE,PTS_FIFO_OFF);
		dwcount=0;
		while ((DVReadReg(0x264)&0x20) != 0) // check bit 2,3 and bit 5
		{
			KeStallExecutionProcessor(1);
			if(dwcount++ > 0xfff0)
				break;
		}

		DVWriteREG(0x204,DVReadReg(0x204)|0x80000L);	// reset PTS fifo		
		dwval = DVReadDRAM(0x200);
		DVWriteREG(0x200,(dwval|0x40));       //no audio master
	}

	v_m_speed = (speed > 2000)?4000:speed;	// speed 4000 is very Fast Scan
	v_m_speed = (v_m_speed < 250)?250:v_m_speed;

	if(v_m_speed == 4000 ) // Very Fast Scan
	{
		#ifdef LINE21
			DVWriteREG(SYNC_INT_CTRL,0xa8001 | 0x100);	// LINE21
		#else
			DVWriteREG(SYNC_INT_CTRL,0xa8001);
		#endif
		DVWriteREG(0x268,(DVReadReg(0x268)&0xa0)|0x1);
	}
	else if(v_m_speed > 1000)	//increase speed from 1x
	{
		DVWriteREG(0x214,0x2e4);
		dw210 = DDiv(v_m_frame_period,0x3e8,(DWORD)(v_m_speed));
		DVWriteREG(SYNC_FRAME_PERIOD,dw210);	

	#ifdef LS240
		#ifdef LINE21
			DVWriteREG(SYNC_INT_CTRL,0x28000001L | 0x100);
		#else
			DVWriteREG(SYNC_INT_CTRL,0x28000001L);
		#endif
		DVWriteREG(0x268,(DVReadReg(0x268)&0xa0)|0x2);
	#else
		#ifdef CHANGE_REG274
			#ifdef LINE21
				DVWriteREG(SYNC_INT_CTRL,0xa8001 | 0x100); // LINE21
			#else
				DVWriteREG(SYNC_INT_CTRL,0xa8001);
			#endif
			DVWriteREG(0x268,(DVReadReg(0x268)&0xa0)|0x2);
		#else
			#ifdef LINE21
				DVWriteREG(SYNC_INT_CTRL,0x220401L | 0x100); // LINE21
			#else
				DVWriteREG(SYNC_INT_CTRL,0x220401L);
			#endif
		#endif
	#endif
	}
	else if(v_m_speed < 1000)	//decrease speed from 1x
	{
		DVWriteREG(SYNC_FRAME_PERIOD,v_m_frame_period);
		dw214 = DDiv(0x2e4,0x3e8,(DWORD)(v_m_speed));
		DVWriteREG(0x214,dw214);
	#ifdef LS240
		DVWriteREG(0x200,(DWORD)( DVReadReg(0x200) | 0x1 ));	// Enable STC
		DVWriteREG(0x268,DVReadReg(0x268)&0xa0);

		#ifdef LINE21
			DVWriteREG(SYNC_INT_CTRL,0x88000001L | 0x100);
		#else
			DVWriteREG(SYNC_INT_CTRL,0x88000001L);
		#endif
	#else
		#ifdef CHANGE_REG274
			DVWriteREG(0x200,(DWORD)( DVReadReg(0x200) | 0x1 ));	// Enable STC
			DVWriteREG(0x268,DVReadReg(0x268)&0xa0);
			#ifdef LINE21
				DVWriteREG(SYNC_INT_CTRL,0x228001L | 0x100); // LINE21
			#else
				DVWriteREG(SYNC_INT_CTRL,0x228001L);
			#endif
		#else
			#ifdef LINE21
				DVWriteREG(SYNC_INT_CTRL,0x220001L | 0x100); // LINE21
			#else
				DVWriteREG(SYNC_INT_CTRL,0x220001L);
			#endif
		#endif
	#endif
	}
	else	//speed == 1000
	{
		DVWriteREG(SYNC_FRAME_PERIOD,v_m_frame_period);
		DVWriteREG(0x214,0x2e4);
	#ifndef LS240
		#ifndef CHANGE_REG274
			#ifdef LINE21
				DVWriteREG(SYNC_INT_CTRL,0xe0001L | 0x100); // LINE21
			#else
				DVWriteREG(SYNC_INT_CTRL,0xe0001L);
			#endif
		#endif
	#endif
	}
}

/////////////////////////////////////////////////////////////////////////////////

void LUXVideoSetVPM(BOOL onoff, int type)
{
DWORD val=0;

	v_m_vga = type;

	if(v_m_fullscrn)
		return;

	if (!eprom[EPROM_TVOUT])
		val = 0xb4;
	else
		val = 0xc0;

	v_m_VPM = onoff;

	if (onoff) 
	{
	#ifdef LS240

		DVWriteREG(0x300,0x12c5L);	//

		if((type == S3_VGA))	//HREFL_VREFL
		{
			DVWriteREG(0x37c,0x370000a4L);	//
		}
		else if(type == VMI_VGA)	//HREFL_VREFH
		{
			DVWriteREG(0x37c,0x170010a4L);
		}
		else if(type == HH_VL_VGA)
		{
			DVWriteREG(0x37c,0x170008a4L);
		}
		else if(type == HH_VH_VGA)
		{
			DVWriteREG(0x37c,0x170018a4L);
		}
		else if(type == HH_VL_16_VGA)
		{
			DVWriteREG(0x300,0x800012c5L);	//
            DVWriteREG(0x37c,0x1f0004c4L);
		}

		DVWriteREG(0x314,0xb40600L|val);	//

		if( type == CCIR656_VGA )
		{
			DVWriteREG(0x37c,0x11003034L);	//
			DVWriteREG(0x314,0xf00600L|val);	//
		}
		else if ( type == HH_VL_16_VGA )
		{
			DVWriteREG(0x314,0xf40600L|val);	//
		}
	#else
		//Settings for LS220 - 8bit Video Port
		if((type == S3_VGA))	//HREFL_VREFL
		{
			DVWriteREG(0x300,0x3e028189L);	//
		}
		else if(type == VMI_VGA)	//HREFL_VREFH
		{
			DVWriteREG(0x300,0x1e128189L);	//
		}
		else if(type == HH_VL_VGA)
		{
			DVWriteREG(0x300,0x1e0a8189L);	//
		}
		else if(type == HH_VH_VGA)
		{
			DVWriteREG(0x300,0x3e1a8189L);	//
		}

		DVWriteREG(0x314,0xb40600L|val);	//

		if( type == CCIR656_VGA )
		{
			DVWriteREG(0x300,0x1210d189L);	//
			DVWriteREG(0x314,0xf00600L|val);	//
		}
	#endif
	} 
	else	
	{
		#ifdef LS240
			DVWriteREG(0x37c,0x00000084L);	
		#else
			DVWriteREG(0x300,0x128189L);	//
		#endif
		DVWriteREG(0x314,0x200600L|val);	//``
	}
	
	if( type == CCIR656_VGA )
		DVWriteREG(0x304,0x620b000aL);	//
	else
		DVWriteREG(0x304,0x220b000aL);	//

	if(type==HH_VH_VGA)
	{
		DVWriteREG(0x308,0x69a00f2L);	//to make sure that we start at an even cropping coord
	}
	else if(type == S3_VGA)
	{
		DVWriteREG(0x308,0x69a00f4L);
	}
	else
		DVWriteREG(0x308,0x69b00f3L);	//

	if (!eprom[EPROM_TVOUT]) 
	{
		DVWriteREG(0x30c,0x1050014L);	//

		if ( v_m_vga == HH_VL_16_VGA )
			DVWriteREG(0x318,0xa200107L);     //
		else
			DVWriteREG(0x318,0xf0107L);	//

		DVWriteDRAM(DSPMEM_LOCK,DDiv(height,0x400L,480));
	} 
	else 
	{
		DVWriteREG(0x30c,0x1350014L);	//

		if ( v_m_vga == HH_VL_16_VGA )
		{
			/*
			DVWriteREG(0x318,0xa200107L);     //
			DVWriteREG(0x30c,0x1050004L);	//
			*/
			DVWriteREG(0x318,0xa200137L);     //
			DVWriteREG(0x30c,0x1350014L);	//

		}
		else
			DVWriteREG(0x318,0xa200139L);     //

		DVWriteDRAM(DSPMEM_LOCK,DDiv(height,0x355L,480)+1);
	}

    

	//This is not originally in this function, but
	//as soon as we detect the type of vga we should
	//pgm correct subpic pos
	if(v_m_vga == CCIR656_VGA)
	{
		if ( v_m_VideoSrc_NTSC ) // NTSC
			DVWriteREG(0x3d4 ,0x280076);
		else
			DVWriteREG(0x3d4 ,0x240076);
	}
	else if ( v_m_vga == HH_VL_16_VGA )
	{
		if ( v_m_VideoSrc_NTSC ) // NTSC
			DVWriteREG(0x3d4,0x260073);
		else
		{
			//DVWriteREG(0x3d4,0x50075);
			DVWriteREG(0x3d4,0x240075);
		}
	}
	else
		DVWriteREG(0x3d4, 0x280070/*0x270076*/);

}

/////////////////////////////////////////////////////////////////////////////////

void LUXVideoStep()
{
DWORD dwVal;
DWORD reg180;
	
	#ifdef DBG
		//DbgPrint("luxdvd : LUXVideoStep\n");
	#endif

	#ifdef CHANGE_REG274
	v_m_speed = 2000;	// don't send PTS
	#endif

	dwVal = DVReadDRAM(0x200);
	DVWriteREG(0x200,(dwVal&0xfffe));       //stop STC

	dwVal = DVReadDRAM(0x200);
	DVWriteREG(0x200,(dwVal|0x40));       //no audio master

#ifdef LS240
	#ifdef LINE21
		DVWriteREG(SYNC_INT_CTRL,0x28008001L|0x100);
	#else
		DVWriteREG(SYNC_INT_CTRL,0x28008001L);
	#endif
	DVWriteREG(0x268,(DVReadReg(0x268)&0xa0)|0x10);	// Step
#else
	#ifdef CHANGE_REG274
		#ifdef LINE21
			DVWriteREG(SYNC_INT_CTRL,0xa8001L | 0x100); // LINE21
		#else
			DVWriteREG(SYNC_INT_CTRL,0xa8001L);
		#endif
		DVWriteREG(0x268,(DVReadReg(0x268)&0xa0)|0x10);	// Step
	#else
		#ifdef LINE21
			DVWriteREG(SYNC_INT_CTRL,0x228000L | 0x100); // LINE21
		#else
			DVWriteREG(SYNC_INT_CTRL,0x228000L);
		#endif
	#endif
#endif

	reg180 = DVReadReg(MPGVID_CONTROL) & 0x1e0;

	DVWriteREG(MPGVID_CONTROL,reg180|0x4);   // start pointers, was 6

}

/////////////////////////////////////////////////////////////////////////////////

void LUXVideoSetGamma(int idx)
{
int	i;
DWORD	tmp;

	m_gamma = idx;

	if ( m_gamma > 9 || m_gamma < 0 )
		m_gamma = 1;

	#ifdef LS240
		//Set up LS240 for Gamma correction
		tmp = DVReadReg(0x300);
		tmp = (DWORD)(tmp|0x40000L)&0xfffcffff;	
		DVWriteREG(0x300,tmp);
	#endif

	for(i=0;i<8;i++) 
	{
		DVWriteREG(0x330+i*4,gamma[m_gamma][i]);
	}
	tmp = DVReadReg(0x304);
	DVWriteREG(0x304,tmp|0x20000000L);
}

/////////////////////////////////////////////////////////////////////////////////

void LUXVideoSetChroma(int idx)
{
	int	i;
	DWORD tmp;

	m_chroma = idx;

	if ( m_chroma > 9 || m_chroma < 0 )
		m_chroma = 1;

#ifdef LS240

	//enable modification of U component (BLUE)
	tmp = DVReadReg(0x300);
	tmp = (DWORD)(tmp|0x20000L)&0xfffaffff;	
	DVWriteREG(0x300,tmp);

	for ( i=0 ; i < 7 ; i++ )
	{
		DVWriteREG(0x330+4*i,chroma_U[m_chroma][i]);
	}

	//enable writes to V component (RED)
	tmp = DVReadReg(0x300);
	tmp = (DWORD)(tmp|0x10000L)&0xfff9ffff;	
	DVWriteREG(0x300,tmp);

	for ( i=0 ; i < 7 ; i++ )
	{
		DVWriteREG(0x330+4*i,chroma_V[m_chroma][i]);
	}


	tmp = DVReadReg(0x304);
	DVWriteREG(0x304,tmp|0x40000000L);

#endif

}

/////////////////////////////////////////////////////////////////////////////////

BOOL LUXVideoSetZoom(DWORD dwlt, DWORD dwrb)
{
WORD left=0,top=0,right=0,bottom=0;
DWORD hzoom=0, vzoom=0;
DWORD y_start=0, uv_start=0, vert_start=0;
DWORD dwtmp1=0, dwtmp2=0;
static DWORD reg304 = 0;

	left = (WORD)( (dwlt>>16) & 0xffff );
	top = (WORD)( dwlt & 0xffff );
	right = (WORD)( (dwrb>>16) & 0xffff );
	bottom = (WORD)( dwrb & 0xffff );

	//Walter will implement zoom for half-D1 later
	if( (width<700) && (height!=480) )
		return TRUE;

	if( (bottom-top)<32 )
	{
	/*
	reg 0x20c must be a multiple of 32
	this zoom region height is not 32lines high
	hence cant pgm sync wait reg 0x20c
	*/
		return FALSE;
	}
	
	hzoom = (DWORD)DDiv((DWORD)(right-left),0x800,720);
	if(hzoom==0)
		hzoom=0x800;
	
	if(!eprom[EPROM_TVOUT]) {
		vzoom = (DWORD)DDiv((DWORD)(bottom-top),0x400,480);
		if(vzoom==0)
			vzoom=0x400;
	} else {
		vzoom = (DWORD)DDiv((DWORD)(bottom-top),0x355,480);
		if(vzoom==0)
			vzoom=0x355;
	}

	y_start = (DWORD)(left << 4);	//no fractional part
	uv_start = (DWORD)DDiv(1,y_start,2);	//half of the Y start

	//Dan says that the last 4 bits of this should be 0 for zoom
	if(top==0)	// no zoom
		vert_start = 0xf;	//fractional part must be f	
	else	//zooming
	{
		//Walter (1/16/98) : For zoom, the fractional part of Vertical offset should be 0
		//to avoid jitter. For un-zoom it should be 0xf
		vert_start = (DWORD)(top << 4);
	}

	DVWriteREG(0x31c,y_start);

	//Dan says that we need to add 10h to this for better zoom quality
	DVWriteREG(0x320,(DWORD)(uv_start+0x10));

	DVWriteREG(0x324,vert_start);
	DVWriteREG(0x328,hzoom);
	DVWriteREG(0x32c,vzoom);
	DVWriteDRAM(DSPMEM_LOCK,vzoom);
			
	//pgm 20c - vid line reached

	if(bottom == 480)	//default
		dwtmp1 = 2;
	else
	{	//divide by 16 and add 1
		//dwtmp1 = (top >> 4) + 1;
		//dwtmp1 *= 2;	//ask harry why we x2

		//thei value has to be a multiple of 8
		dwtmp1 = (top >> 3) + 1;
	}
	DVWriteREG(0x20c,dwtmp1);

#ifdef LS240
	if ( (bottom-top) != height )	
	{
		v_m_zoomin = TRUE;
		
		if ( ac3_flag == 1 ) // only for AC3
		{
			DVWriteREG(0x268,DVReadReg(0x268)|0x20);	// DSP need this 
			DVWriteREG(0x274,0xc8000001);	// zoom in , force MPEG decode early
		}
	}
	else
	{
		v_m_zoomin = FALSE;
		DVWriteREG(0x268,DVReadReg(0x268)&0xffdf);	// DSP need this
		DVWriteREG(0x274,0x88000001);	// zoom out
		DVWriteREG(0x324,0x1f);	// restore 0x324
		DVWriteDRAM(DSPMEM_CMD,0x8e);	// do field detect again
		Wait();
	}
#else
	#ifdef CHANGE_REG274
		if ( (bottom-top) != height )
		{
			v_m_zoomin = TRUE;
	
			if ( eprom[EPROM_TVOUT] && !v_m_VideoSrc_NTSC && ( reg304 == 0 ) )	// PAL Src && PAL Output
			{																	// Need to adjust 0x304 to prevent the stripe on screen
				reg304 = DVReadReg(0x304);
				DVWriteREG(0x304,(reg304&0xfff0fff0)|0x50006);
			}

			if ( ac3_flag == 1 ) // only for AC3
			{
				DVWriteREG(0x268,DVReadReg(0x268)|0x20);	// DSP need this 
				DVWriteREG(0x274,0x328001);	// zoom in , force MPEG decode early
			}
		}
		else
		{
			v_m_zoomin = FALSE;
			
			if ( eprom[EPROM_TVOUT] && !v_m_VideoSrc_NTSC && ( reg304 != 0 ) )
			{
				DVWriteREG(0x304,reg304);
				reg304 = 0;
			}

			DVWriteREG(0x268,DVReadReg(0x268)&0xffdf);	// DSP need this
			DVWriteREG(0x274,0x228001);	// zoom out

			if ( (eprom[EPROM_TVOUT] && v_m_VideoSrc_NTSC) || (!eprom[EPROM_TVOUT] && !v_m_VideoSrc_NTSC) ) // ( PAL output and NTSC Source ) or ( NTSC output and PAL Source )
				DVWriteREG(0x324,0x10);	// restore 0x324
			else
				DVWriteREG(0x324,0x1f);	// restore 0x324

			DVWriteDRAM(DSPMEM_CMD,0x8e);	// do field detect again
			Wait();
		}
	#else
		DVWriteREG(0x274,0x220001);
	#endif
#endif

	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////////

void LUXVideoSetForMenu(BOOL menu)
{
	isMenu = menu;

	if ( !menu )
		return;

	b_LetterBox = 0;
	//removes any seetings for letter box

	if(v_m_vga == CCIR656_VGA)
		DVWriteREG(0x3d4 ,0x280076);
	else if ( v_m_vga == HH_VL_16_VGA )
		DVWriteREG(0x3d4,0x260073);
	else
		DVWriteREG(0x3d4, 0x280070/*0x270076*/);
	
	DVWriteREG(0x328,DDiv((DWORD)width,0x800L,720));	

	if (!eprom[EPROM_TVOUT]) 
	{
		DVWriteREG(0x30c ,0x1050014);
		DVWriteDRAM(DSPMEM_LOCK,DDiv(height,0x400L,480));
	} 
	else	//PAL
	{
		DVWriteREG(0x30c ,0x1350014L);
		DVWriteDRAM(DSPMEM_LOCK,DDiv(height,0x355L,480)+1);
	}

	DVWriteREG(0x31c ,0x0);

	//do zoom-out when fullscr and playing menus
	LUXVideoSetFullScreen(v_m_fullscrn);	// do menu

	#ifdef	AURAVISION
		DVWriteREG(0x320 ,0x20);
	#else
		DVWriteREG(0x320 ,0x0);
	#endif
}	

/////////////////////////////////////////////////////////////////////////////////

void LUXVideoSetPanScan(BOOL on)
{
	if(on)
	{
		v_m_PanScan = TRUE;

		DVWriteREG(0x328 ,0x600);
		DVWriteREG(0x31c ,0x5a0);
		DVWriteREG(0x320 ,0x2d0);

		if(v_m_vga == CCIR656_VGA)
			DVWriteREG(0x3d4 ,0x280076);
		else
			DVWriteREG(0x3d4, 0x280070/*0x270076*/);
	}
	else
	{
		v_m_PanScan = FALSE;
		
		DVWriteREG(0x328,DDiv((DWORD)width,0x800L,720));	
		DVWriteREG(0x31c ,0x0);
		DVWriteREG(0x320 ,0x0);
		DVWriteREG(0x30c ,0x1050014);
		if(v_m_vga == CCIR656_VGA)
			DVWriteREG(0x3d4 ,0x280076);
		else
			DVWriteREG(0x3d4, 0x280070/*0x270076*/);
	}

	if (!eprom[EPROM_TVOUT]) 
	{
		DVWriteREG(0x30c ,0x1050014);
		DVWriteREG(0x32c,DDiv((DWORD)height,0x400L,480));	
		DVWriteDRAM(DSPMEM_LOCK,DDiv((DWORD)height,0x400L,480));
	} 
	else 
	{
		DVWriteREG(0x30c ,0x1350014);
		DVWriteREG(0x32c,DDiv((DWORD)height,0x355L,480)+1);	
		DVWriteDRAM(DSPMEM_LOCK,DDiv((DWORD)height,0x355L,480)+1);
	}
}


/////////////////////////////////////////////////////////////////////////////////

void LUXVideoMenu(BOOL menu)
{
DWORD reg204;

	isStillMenu = menu;

#ifdef LS240
	reg204 = DVReadReg(0x204);	// check bit 16 , set to 1 for menu 

	if ( menu )
		DVWriteREG(0x204,reg204|0x10000);	// set to 1 
	else
		DVWriteREG(0x204,reg204&0xfffeffff);// set to 0
#endif
}

/////////////////////////////////////////////////////////////////////////////////

void LUXVideoPan(int pos)
{
DWORD dwy;
DWORD dwuv;

	if(v_m_PanScan)
	{
		dwy = (DWORD)(1440+pos);
		dwy &= 0xfff0;	//no fraction
		dwuv = (DWORD)DDiv(1,dwy,2);
		dwuv &= 0xfff0;	//no fraction

		DVWriteREG(0x31c,dwy);
		DVWriteREG(0x320,dwuv);
	}
}


/////////////////////////////////////////////////////////////////////////////////

BOOL LUXVideoSetFullScreen(BOOL val)
{
DWORD	tmp;
BYTE	addr;

	if ( (eprom[EPROM_BOARDTYPE]&0x1) != 1) // only board type 1 and 3 are full screen switch
	{
		if(v_m_vga == CCIR656_VGA)
			DVWriteREG(0x3d4 ,0x280076);
		else
			DVWriteREG(0x3d4, 0x280070/*0x270076*/);

		return FALSE;
	}

	tmp = DVReadReg(0x350)|0x0e0e00;

	if (val)	//FULLSCREEN ON
	{
		LUXVideoTurn_Off_TV(TRUE);	// Turn off TV

		v_m_fullscrn = TRUE;

		DVWriteREG(0x350,tmp&0x4fff700);	// 0x4ff0700, pull bit2,1 to high

		//COMMON SETTINGS
		DVWriteREG(0x300,0x03e123013);
		DVWriteREG(0x304,0x20b000a);
		
		if ( !v_m_VideoSrc_NTSC )	// PAL Sources
		{
			DVWriteREG(0x30c,0x02030012);
			DVWriteREG(0x308,0x03480098);	// H shift , value from Dan
		}
		else
		{
			DVWriteREG(0x30c,0x02000030);
			DVWriteREG(0x308,0x03500090);	// H shift , value from Dan
		}

//		DVWriteREG(0x314,0x06400366);
		DVWriteREG(0x314,0x06600366);	// H shift , value from Dan
		DVWriteREG(0x318,0x06cc0206);

		DVWriteREG(0x3d4,0x2e008d);	

		if(v_m_mpeg1)	//MPEG1 settings same for NTSC/PAL
		{
			DVWriteREG(0x31c,0x0);
			DVWriteREG(0x320,0x0);
			DVWriteREG(0x324,0x4);
			DVWriteREG(0x328,0x7e0);
			DVWriteREG(0x32c,0x200);
		}
		else	//MPEG2 Settings
		{
			if ( eprom[EPROM_TVOUT] ) // PAL output , and Full Scr on
				DVWriteREG(0x3d8,0x4000400);

			if( isMenu || isStillMenu )	//FOR MENUS settings same for NTSC/PAL 
			{							// Maybe we don't need isStillMenu here ?!
				DVWriteREG(0x31c,0x0);
				DVWriteREG(0x320,0x0);
				#ifndef DO_NOT_TOUCH_REG324	// SYNC will take care of 0x324
					DVWriteREG(0x324,0xf);
				#endif
				DVWriteREG(0x328,0x1000);	
			}
			else	//VIDEO settings same for NTSC/PAL
			{
				DVWriteREG(0x31c,0x400);
				DVWriteREG(0x320,0x200);
				#ifndef DO_NOT_TOUCH_REG324	// SYNC will take care of 0x324
					DVWriteREG(0x324,0xf);
				#endif
				DVWriteREG(0x328,0xd80);
			}

			if ( !v_m_VideoSrc_NTSC )	// PAL Sources
			{
				DVWriteREG(0x3d4,0x2008b);
				DVWriteREG(0x32c,0x440);
				DVWriteDRAM(DSPMEM_LOCK,0x440L);
			}
			else
			{
				DVWriteREG(0x32c,0x400);
				DVWriteDRAM(DSPMEM_LOCK,0x400L);
			}
		}
		
		/*
		if ( m_OSD != 0xff )
			OSDInit(m_OSD);
		*/
	}
	else	//fullscreen OFF
	{

		v_m_fullscrn = FALSE;
		
		LUXVideoTurn_Off_TV(FALSE);	// Turn on TV

		DVWriteREG(0x350,tmp);		// 0x4ff0f00

		if(v_m_vga == CCIR656_VGA)
			DVWriteREG(0x3d4 ,0x280076);
		else
			DVWriteREG(0x3d4, 0x280070/*0x270076*/);

		DVWriteREG(0x328,DDiv(width,0x800L,720));	//

		LUXVideoSetVPM(v_m_VPM,v_m_vga);

		//NEW - reset the changes made to avoid video noise
		if( !v_m_mpeg1 )
		{
			DVWriteREG(0x328,DDiv(width,0x800L,720));

			if ( eprom[EPROM_TVOUT] && v_m_VideoSrc_NTSC ) // PAL output , NTSC Src
				DVWriteREG(0x3d8,0x3550400);
			else 
				DVWriteREG(0x3d8,0x4000400);

			if (!eprom[EPROM_TVOUT])
			{
				DVWriteREG(0x32c,DDiv(height,0x400L,480));	//
				DVWriteDRAM(DSPMEM_LOCK,DDiv((DWORD)height,0x400L,480));	
			}
			else
			{
				DVWriteREG(0x32c,DDiv(height,0x355L,480));	//
				DVWriteDRAM(DSPMEM_LOCK,DDiv((DWORD)height,0x355L,480)+1);	
			}
			
			DVWriteREG(0x31c,0x00);
			DVWriteREG(0x320,0x00);
			//DVWriteREG(0x324,0xf);
			#ifndef DO_NOT_TOUCH_REG324	// SYNC will take care of 0x324
				if( DVReadReg(0x32c) != 0x400 )
					DVWriteReg(0x324,0x0);
				else
					DVWriteReg(0x324,0xf);
			#endif
		}

		/*
		if ( m_OSD != 0xff )
			OSDExit(m_OSD);
		*/
	}

	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////////

void LUXVideoSeq_end()
{
	DVWriteREG(0x278,0x4000);
	DVWriteREG(0x274,DVReadReg(0x274)|0x4000);
}

/////////////////////////////////////////////////////////////////////////////////

void LUXVideoTurn_Off_TV(BOOL off)
{
BYTE	addr;

	if ( off )
	{
		switch(v_m_tvencoder) 
		{
		case AD7175:
		case AD7176:
			if (v_m_tvencoder == AD7175)
				addr = 0xd4;
			else
				addr = 0x54;
			send_i2c(addr,0x1,0x78);	// turn off TV output
			break;

		case CS4952:
		case CS4953:
			send_i2c(0x80,0x04,0xf0);	// turn off TV output
			break;

		case BT865:
		case BT864:
			send_i2c(0x8a,0xbc,0x9);
			break;
		}
	}
	else
	{
		switch(v_m_tvencoder) 
		{
		case AD7175:
		case AD7176:
			if (v_m_tvencoder == AD7175)
				addr = 0xd4;
			else
				addr = 0x54;
			send_i2c(addr,0x1,0x0);	// turn on TV output
			break;

		case CS4952:
		case CS4953:
			send_i2c(0x80,0x04,0x0f);	// turn on TV output
			break;
		case BT865:
		case BT864:
			send_i2c(0x8a,0xbc,0x1);
			break;
		}
	}
}

/////////////////////////////////////////////////////////////////////////////////

DWORD *LUXVideoUserData()
{
DWORD *dwaddr;


	dwaddr =(DWORD *)(luxbase+DVReadDRAM(DSPMEM_BASE+0xff74)+DRAM_BASE);

	return dwaddr;
}

/////////////////////////////////////////////////////////////////////////////////

void LUXVideoSet_Fcode(BYTE fcode)
{
DWORD reg180;
	reg180 = DVReadReg(MPGVID_CONTROL) & 0x1f;

	if ( fcode == 4 )
		DVWriteREG(MPGVID_CONTROL,reg180|0x80);	// off
	else if ( fcode == 2 )
		DVWriteREG(MPGVID_CONTROL,reg180|0x40);	// off
	else
		DVWriteREG(MPGVID_CONTROL,reg180);	// off
}

/////////////////////////////////////////////////////////////////////////////////

void LUXVideoFlush()
{
int i=0;

	for(i=0; i < 5; i++)
		LUXSendData(NULL,ebuf,128,0,0);
}

/////////////////////////////////////////////////////////////////////////////////

#ifdef LS240

void LUXVideoZVEnableTriState()
{
	DVWriteREG(0x37c,DVReadReg(0x37c)&0xe0ffffff);	// clear bit 28-24
}

#endif

/////////////////////////////////////////////////////////////////////////////////

int LuxVideoGetGamma()
{
	return m_gamma;
}

/////////////////////////////////////////////////////////////////////////////////

int LuxVideoGetChroma()
{
	return m_chroma;
}
