windows-nt/Source/XPSP1/NT/drivers/wdm/dvd/mini/dxr2/zivawdm.c
2020-09-26 16:20:57 +08:00

806 lines
19 KiB
C

/******************************************************************************\
* *
* ZIVAWDM.C - ZiVA hardware control API. *
* *
* Copyright (c) C-Cube Microsystems 1996 *
* All Rights Reserved. *
* *
* Use of C-Cube Microsystems code is governed by terms and conditions *
* stated in the accompanying licensing statement. *
* *
\******************************************************************************/
#include "Headers.h"
#pragma hdrstop
#include "boardio.h"
#include "cl6100.h"
#include "tc6807af.h"
#include "fpga.h"
#include "audiodac.h"
#if defined(DECODER_DVDPC)
#include "lukecfg.h"
#include "mvis.h"
#include "dataxfer.h"
#elif defined(ENCORE) || defined(OVATION)
#include "bmaster.h"
#elif defined(EZDVD)
#include "Hostcfg.h"
#include "dataxfer.h"
#include "mvis.h"
#endif
#if defined(ENCORE)
#include "mvstub.h"
#endif
#if defined (LOAD_UCODE_FROM_FILE)
#include "RegistryApi.h"
unsigned char UcodeBuff[150 * 1024]; // Ucode for for loading from file. // test
#else
#if defined(DECODER_DVDPC)
#include "cobra_ux.h"
#else//if defined(ENCORE) || defined(OVATION)
#include "dvd1_ux.h"
//#elif defined(EZDVD)
//#include "ezdvd_ux.h"
#endif
#endif //LOAD_UCODE_FROM_FILE
//*******************************************************************
// Local Types Declaration
//*******************************************************************
typedef enum _PLAY_STATE_COMMAND {
CMD_PLAY = 0,
CMD_PAUSE,
CMD_STOP,
CMD_SCAN,
CMD_STEP,
CMD_SLOWMOTION,
CMD_NONE
} PLAY_STATE_COMMAND;
//*******************************************************************
// Global Variables Declaration
//*******************************************************************
PLAY_STATE_COMMAND gLastCommand = CMD_STOP;
BOOL bPlaybackJustStarted = FALSE;
#if defined (LOAD_UCODE_FROM_FILE)
BOOL
ZivaHW_LoadUCodeFromFile( // Load the microcode based on the microcode Id specified.
PHW_DEVICE_EXTENSION pHwDevExt); // is pHwDevExt
#endif
//
// ZivaHW_Initialize
//
///////////////////////////////////////////////////////////////////////////////
BOOL _stdcall ZivaHw_Initialize( PHW_DEVICE_EXTENSION pHwDevExt )
{
#if defined(DECODER_DVDPC)
DWORD dwDVDAMCCBaseAddress,dwDVDIrq;
#endif
MonoOutInit();
#if defined(DECODER_DVDPC)
if (!InitLukeCfg(&dwDVDAMCCBaseAddress, &dwDVDIrq))
return FALSE;
InitMvis(pHwDevExt -> dwDVDAMCCBaseAddress);
TV_SetEncoderType(1);
if (!DataTransfer_Init( pHwDevExt -> dwDVDAMCCBaseAddress,dwDVDIrq))
{
MonoOutStr( " Cannot Initialize the AMCC for Bus Mastering " );
return FALSE;
}
#elif defined(ENCORE)
// Initialize Bus Master first
if ( !BMA_Init( pHwDevExt -> dwDVDAMCCBaseAddress, pHwDevExt->bIsVxp524 ) )
{
MonoOutStr( " Cannot Initialize the AMCC for Bus Mastering " );
return FALSE;
}
if ( !FPGA_Init( pHwDevExt -> dwDVDFPGABaseAddress ) )
{
MonoOutStr( " Cannot Initialize the FPGA " );
return FALSE;
}
#elif defined(OVATION)
// Initialize FPGA
if ( !FPGA_Init( pHwDevExt -> dwDVDFPGABaseAddress ) )
{
MonoOutStr( " Cannot Initialize the FPGA " );
return FALSE;
}
// Initialize Bus Master
if ( !BMA_Init( pHwDevExt -> dwDVDAMCCBaseAddress ) )
{
MonoOutStr( " Cannot Initialize the AMCC for Bus Mastering " );
return FALSE;
}
#elif defined(EZDVD)
if (!InitHost(&(pHwDevExt -> dwDVDFPGABaseAddress), NULL))
return FALSE;
BRD_Init(pHwDevExt -> dwDVDAMCCBaseAddress, 0);
InitMvis(0);//parameter ignored
#endif
// Initialize DVD1 chip
if ( !DVD_Initialize( pHwDevExt -> dwDVDHostBaseAddress, pHwDevExt -> dwDVDCFifoBaseAddress ) )
{
MonoOutStr( " Cannot Initialize the DVD1 chip (Board not found at specified address: " );
MonoOutULongHex( pHwDevExt -> dwDVDHostBaseAddress );
MonoOutStr( ") " );
return FALSE;
}
if ( ( DVD_GetHWVersion() == DVD_HW_VERSION_1_0 ) )
{
#ifdef OVATION
if ( !TC6807AF_Initialize( pHwDevExt -> dwDVD6807BaseAddress ) )
{
MonoOutStr( " Cannot Initialize the TC6807AF chip at specified address: " );
MonoOutULongHex( pHwDevExt -> dwDVD6807BaseAddress );
MonoOutStr( ") " );
return FALSE;
}
#endif
}
//
// Disable ZiVA's host interrupt
//
BRD_CloseDecoderInterruptPass();
//
// Load Decoder's firmware
//
#if defined (LOAD_UCODE_FROM_FILE)
if ( !ZivaHW_LoadUCodeFromFile(pHwDevExt) )
{
MonoOutStr(" !!! Ucode Load from file failed. !!!");
return FALSE;
}
#else
if ( !ZivaHW_LoadUCode( ) )
return FALSE;
#endif
#if defined( OVATION )
ADAC_Init( pHwDevExt -> dwDVDFPGABaseAddress );
#elif (DECODER_DVDPC)
ADAC_Init( pHwDevExt -> dwDVDAMCCBaseAddress );
#else
ADAC_Init( (pHwDevExt -> dwDVD6807BaseAddress) - 2 );
#endif // OVATION
// Set default sampling frequency to 48 KHz (AC-3 audio)
ADAC_SetSamplingFrequency( ADAC_SAMPLING_FREQ_48 );
#if 0
// Set interrupt mask for events that we are going to use
if ( !DVD_IntEnable( CL6100_INT_MASK_UND|CL6100_INT_MASK_ERR ) )
return FALSE;
#endif
#if 0
DebugPrint((DebugLevelVerbose,"\nCF_intrpt: %lX", DVD_ReadReg( 0x1c ) ));
DebugPrint((DebugLevelVerbose," CF_count: %lX", DVD_ReadReg( 0x1d ) ));
DebugPrint((DebugLevelVerbose," CF_command: %lX", DVD_ReadReg( 0x1f ) ));
DebugPrint((DebugLevelVerbose," Host_contrl: %lX", DVD_ReadReg( 0 ) ));
DebugPrint((DebugLevelVerbose,"\nDRAM_SUBP_FIFO_ST: %lX", DVD_ReadDRAM( 0x1722*4 ) ));
DebugPrint((DebugLevelVerbose," RD_PTR: %lX", DVD_ReadDRAM( 0x1721*4 ) ));
DebugPrint((DebugLevelVerbose," WR_PTR: %lX", DVD_ReadDRAM( 0x1720*4 ) ));
#endif
return TRUE;
}
//
// CL6100SD_LoadUCode
//
///////////////////////////////////////////////////////////////////////////////
#if defined (LOAD_UCODE_FROM_FILE)
BOOL LoadUcode(BYTE * pbtUcode)
{
// White sub picture palettes.
DWORD dwPalletes[16] = { 0x00b08080,
0x00b08080,
0x00b08080,
0x00b08080,
0x00b08080,
0x00b08080,
0x00b08080,
0x00b08080,
0x00b08080,
0x00b08080,
0x00b08080,
0x00b08080,
0x00b08080,
0x00b08080,
0x00b08080,
0x00b08080 };
#if defined(DECODER_DVDPC) || defined(EZDVD)
DataTransfer_Reset();
#else
BMA_Reset();
FPGA_Clear( FPGA_SECTOR_START );
#endif
if ( !DVD_LoadUCode( pbtUcode) )
return FALSE;
// Initialize sub picture palettes to white
DVD_SetPalette( dwPalletes );
return TRUE;
}
#else
BOOL _stdcall ZivaHW_LoadUCode( )
{
// White sub picture palettes.
DWORD dwPalletes[16] = { 0x00b08080,
0x00b08080,
0x00b08080,
0x00b08080,
0x00b08080,
0x00b08080,
0x00b08080,
0x00b08080,
0x00b08080,
0x00b08080,
0x00b08080,
0x00b08080,
0x00b08080,
0x00b08080,
0x00b08080,
0x00b08080 };
#if defined(DECODER_DVDPC) || defined(EZDVD)
DataTransfer_Reset();
#else
BMA_Reset();
FPGA_Clear( FPGA_SECTOR_START );
#endif
if ( !DVD_LoadUCode( (BYTE *)(Microcode_Ptr_List[0].Microcode_Seg_Add) ) )
return FALSE;
// Initialize sub picture palettes to white
DVD_SetPalette( dwPalletes );
return TRUE;
}
#endif
//
// ZivaHw_Play
//
///////////////////////////////////////////////////////////////////////////////
BOOL _stdcall ZivaHw_Play( )
{
BOOL bStatus = FALSE;
// Set interrupt mask for events that we are going to use
//#ifndef EZDVD
#ifdef DEBUG
DVD_IntEnable( CL6100_INT_MASK_VSYNC|CL6100_INT_MASK_UND|CL6100_INT_MASK_ERR
|CL6100_INT_MASK_USR ); //sri
#else
DVD_IntEnable( CL6100_INT_MASK_VSYNC|CL6100_INT_MASK_USR );
#endif
//#endif
if (gLastCommand == CMD_PAUSE ||
gLastCommand == CMD_SCAN ||
gLastCommand == CMD_SLOWMOTION )
{
gLastCommand = CMD_PLAY;
bStatus = DVD_Resume( );
// bStatus = DVD_Play( );
}
else if ( gLastCommand != CMD_PLAY )
{
bPlaybackJustStarted = TRUE;
gLastCommand = CMD_PLAY;
bStatus = DVD_Play( );
}
else
bStatus = TRUE;
return bStatus;
}
//
// ZivaHw_Scan
//
///////////////////////////////////////////////////////////////////////////////
BOOL _stdcall ZivaHw_Scan( )
{
BOOL bStatus = FALSE;
if ( gLastCommand != CMD_SCAN )
{
if ( gLastCommand != CMD_STOP )
ZivaHw_Abort( );
gLastCommand = CMD_SCAN;
bStatus = DVD_Scan( 0, 0 );
}
else
bStatus = TRUE;
return bStatus;
}
//
// ZivaHw_SLowMotion
//
///////////////////////////////////////////////////////////////////////////////
BOOL _stdcall ZivaHw_SlowMotion( WORD wRatio )
{
BOOL bStatus = FALSE;
if ( gLastCommand != CMD_SLOWMOTION )
{
gLastCommand = CMD_SLOWMOTION;
bStatus = DVD_SlowMotion( wRatio );
}
else
bStatus = TRUE;
return bStatus;
}
//
// ZivaHw_Pause
//
///////////////////////////////////////////////////////////////////////////////
BOOL _stdcall ZivaHw_Pause( )
{
if (gLastCommand == CMD_PLAY ||
gLastCommand == CMD_SCAN ||
gLastCommand == CMD_SLOWMOTION )
{
gLastCommand = CMD_PAUSE;
return DVD_Pause( );
}
return TRUE;
}
//
// ZivaHw_Reset
//
///////////////////////////////////////////////////////////////////////////////
BOOL ZivaHw_Reset( )
{
//#ifndef EZDVD
#ifdef DEBUG
DVD_IntDisable( CL6100_INT_MASK_VSYNC|CL6100_INT_MASK_UND|CL6100_INT_MASK_ERR
|CL6100_INT_MASK_USR ); //sri
#else
DVD_IntDisable( CL6100_INT_MASK_VSYNC|CL6100_INT_MASK_USR ); //sri
#endif
//#endif
DVD_Reset( );
#if defined(DECODER_DVDPC) || defined(EZDVD)
DataTransfer_Reset();
#else
BMA_Reset();
FPGA_Clear( FPGA_SECTOR_START );
#endif
gLastCommand = CMD_STOP;
return TRUE;
}
//
// ZivaHw_Abort
//
///////////////////////////////////////////////////////////////////////////////
BOOL ZivaHw_Abort( )
{
BOOL bStatus = FALSE;
//INT_STATUS_INFO Info;
//DWORD dwTimeout = 100000;
// Set interrupt mask for events that we are going to use
//#ifndef EZDVD
#ifdef DEBUG
DVD_IntDisable( CL6100_INT_MASK_VSYNC|CL6100_INT_MASK_UND|CL6100_INT_MASK_ERR
|CL6100_INT_MASK_USR ); //sri
#else
DVD_IntDisable( CL6100_INT_MASK_VSYNC|CL6100_INT_MASK_USR ); //sri
#endif
//#endif
if ( gLastCommand != CMD_STOP )
{
gLastCommand = CMD_STOP;
#if defined(DECODER_DVDPC) || defined(EZDVD)
DataTransfer_Reset();
#else
BMA_Reset();
FPGA_Clear( FPGA_SECTOR_START );
#endif
bStatus = DVD_Abort( );
}
else
bStatus = TRUE;
return bStatus;
}
//
// ZivaHw_FlushBuffers
//
///////////////////////////////////////////////////////////////////////////////
BOOL ZivaHw_FlushBuffers( )
{
gLastCommand = CMD_NONE; // Allow any next command
DVD_Abort( );
#if defined(DECODER_DVDPC) || defined(EZDVD)
DataTransfer_Reset();
#else
BMA_Reset();
FPGA_Clear( FPGA_SECTOR_START );
#endif
return TRUE;
}
//
// ZivaHw_GetState
//
///////////////////////////////////////////////////////////////////////////////
ZIVA_STATE ZivaHw_GetState( )
{
ZIVA_STATE zState;
if ( gLastCommand == CMD_PLAY )
zState = ZIVA_STATE_PLAY;
else if ( gLastCommand == CMD_PAUSE )
zState = ZIVA_STATE_PAUSE;
else if ( gLastCommand == CMD_STOP )
zState = ZIVA_STATE_STOP;
else if ( gLastCommand == CMD_SCAN )
zState = ZIVA_STATE_SCAN;
else if ( gLastCommand == CMD_STEP )
zState = ZIVA_STATE_STEP;
else if ( gLastCommand == CMD_SLOWMOTION )
zState = ZIVA_STATE_SLOWMOTION;
return zState;
}
//
// ZivaHW_GetNotificationDirect
//
/////////////////////////////////////////////////////////////////////
BOOL ZivaHW_GetNotificationDirect( PINT_STATUS_INFO pInfo )
{
INTSOURCES IntSrc;
//MonoOutStr("[Get notification direct ");
pInfo -> dwStatus = DVD_Isr( &IntSrc );
pInfo -> dwButton = IntSrc.DVDIntHLI;
pInfo -> dwError = IntSrc.DVDIntERR;
pInfo -> dwBuffer = IntSrc.DVDIntBUFF;
pInfo -> dwUnderflow = IntSrc.DVDIntUND;
pInfo -> dwAOR = IntSrc.DVDIntAOR;
pInfo -> dwAEE = IntSrc.DVDIntAEE;
//MonoOutStr("]");
return TRUE;
}
void ZivaHW_ForceCodedAspectRatio(WORD wRatio)
{
DVD_ForceCodedAspectRatio(wRatio);
}
void ZivaHw_SetDisplayMode( WORD wDisplay, WORD wMode )
{
DVD_SetDisplayMode(wDisplay,wMode );
}
void ZivaHw_SetVideoMode(PHW_DEVICE_EXTENSION pHwDevExt)
{
#if defined (DECODER_DVDPC) || defined(EZDVD)
// TV_SetEncoderType(1);
SetTVSystem(pHwDevExt->VidSystem);
DVD_NewPlayMode( ZIVA_STREAM_TYPE_MPEG_PROGRAM, pHwDevExt->VidSystem );
#else if(ENCORE)
BOOL bSystem = pHwDevExt->VidSystem == PAL ? FALSE:TRUE;
SetMacroVisionLevel( bSystem, pHwDevExt->ulLevel );
DVD_NewPlayMode( ZIVA_STREAM_TYPE_MPEG_PROGRAM, pHwDevExt->VidSystem );
#endif
}
#if defined (LOAD_UCODE_FROM_FILE)
#define ENTRY_UCODE_FILE L"Microcode"
#define ENTRY_DEFAULT_UCODE_FILE L"Dvd1.Ux"
BOOL
ZivaHW_LoadUCodeFromFile( // Load the microcode based on the microcode Id specified.
PHW_DEVICE_EXTENSION pHwDevExt) // is pHwDevExt
{
NTSTATUS status;
HANDLE hKeyPdo;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING uniFileName;
HANDLE hFile;
IO_STATUS_BLOCK iosb;
FILE_STANDARD_INFORMATION FileInfo;
PUCHAR pFileDataPtr, pSaveFileDataPtr;
WCHAR pSection[] = L"FileNames";
WCHAR pwchUXFileName[255];
BOOL fResult = FALSE;
/*
WCHAR pwchEncUXFileName[255];// = L"\\SystemRoot\\system32\\drivers\\c3m2_enc.ux";
WCHAR pwchDecUXFileName[255];// = L"\\SystemRoot\\system32\\drivers\\c3m2_dec.ux";
short sLength;
WCHAR pSection[] = L"FileNames";
*/
MonoOutStr("Loading Ucode from File ");
status = IoOpenDeviceRegistryKey( pHwDevExt->pPhysicalDeviceObj, // my real PDO
PLUGPLAY_REGKEY_DRIVER, // pertinent to my device
KEY_ALL_ACCESS, // all acess
&hKeyPdo); // handle returned
if ( !NT_SUCCESS( status ))
{
MonoOutStr("Failed to obtain Key handle ");
return FALSE;
}
if (!REG_GetPrivateProfileString(
pSection,
ENTRY_UCODE_FILE,
ENTRY_DEFAULT_UCODE_FILE,
pwchUXFileName,
sizeof(pwchUXFileName),
hKeyPdo))
{
MonoOutStr("Failed to obtain Ucode file name form registry ");
return FALSE;
}
pSaveFileDataPtr = pFileDataPtr = NULL;
uniFileName.Length = wcslen(pwchUXFileName) * sizeof(WCHAR);
uniFileName.MaximumLength = wcslen(pwchUXFileName) * sizeof(WCHAR);
uniFileName.Buffer = pwchUXFileName;
//
// Read the Microcode file and load it.
//
// Open the file.
InitializeObjectAttributes(
&ObjectAttributes,
&uniFileName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
status = ZwCreateFile(
&hFile,
GENERIC_READ, // || SYNCHRONIZE,
&ObjectAttributes,
&iosb,
NULL, // allocate size
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT, //FILE_SEQUENTIAL_ONLY, use sync no alert
NULL, // eabuffer
0); // ealength
if ( !NT_SUCCESS( status ))
{
MonoOutStr("Can not create ucode file\n");
hFile = NULL;
return fResult;
}
// Get file lengh and allocate memory to read complete file.
status = ZwQueryInformationFile(hFile, &iosb, &FileInfo, sizeof(FileInfo), FileStandardInformation);
if ( !NT_SUCCESS( status ))
{
MonoOutStr(" Can not get ucode file length ");
ZwClose( hFile );
hFile = NULL;
return fResult;
}
#if 0
pFileDataPtr = ExAllocatePool(PagedPool , FileInfo.EndOfFile.LowPart);
if (pFileDataPtr == NULL)
{
MonoOutStr(" Can not allocate pFileDataPtr ");
ZwClose( hFile );
hFile = NULL;
return fResult;
}
#endif
pFileDataPtr = UcodeBuff;
pSaveFileDataPtr = pFileDataPtr;
// Read all the data from the file into buffer allocated.
status = ZwReadFile(
hFile,
NULL, // event
NULL, // apcroutine
NULL, // apc context
&iosb,
pFileDataPtr,
FileInfo.EndOfFile.LowPart,
NULL, //FILE_USE_FILE_POINTER_POSITION
NULL); // key
if ( !NT_SUCCESS( status ) || iosb.Information <= 0 )
{
MonoOutStr(" Can not read ucode file ");
ZwClose( hFile );
hFile = NULL;
ExFreePool(pSaveFileDataPtr);
pFileDataPtr = NULL;
return fResult;
}
if (LoadUcode(pFileDataPtr))
fResult = TRUE;
// Close the file and release the allocated buffer.
ZwClose( hFile );
hFile = NULL;
#if 0
ExFreePool(pSaveFileDataPtr);
pFileDataPtr = NULL;
#endif
return fResult;
}
#endif
DWORD SwapDWORD(DWORD dwData)
{
dwData = (((dwData & 0x000000FF) << 24) | ((dwData & 0x0000FF00) << 8)
|((dwData & 0x00FF0000) >> 8)|((dwData & 0xFF000000) >> 24));
return dwData;
}
BOOL ZivaHw_GetUserData(PHW_DEVICE_EXTENSION pHwDevExt)
{
DWORD dwUserReadPtr;
DWORD dwUserWritePtr;
DWORD UserDataBufferStart;
DWORD UserDataBufferEnd;
int i =0;
BOOL fCCData = FALSE;
DWORD dwData=0;
DWORD dwUserDataBufferSize=0;
dwUserReadPtr = DVD_ReadDRAM( USER_DATA_READ );
dwUserWritePtr = DVD_ReadDRAM( USER_DATA_WRITE );
UserDataBufferStart = DVD_ReadDRAM( USER_DATA_BUFFER_START );
UserDataBufferEnd = DVD_ReadDRAM( USER_DATA_BUFFER_END );
// Check for DRAM Buffer Overflow
if ( dwUserReadPtr == 0xFFFFFFFF )
{
// Set Read Ptr
DVD_WriteDRAM( USER_DATA_READ, dwUserWritePtr );
MonoOutStr(" UsrBufferOverFlow ");
pHwDevExt->fReSync = TRUE;
return fCCData;
}
else
{
if(pHwDevExt->fReSync)
{
dwData = DVD_ReadDRAM( dwUserReadPtr );
if( (dwData & 0xFFFF0000 ) == 0xFEED0000)
{
MonoOutStr(" ReSync After Overflow ");
pHwDevExt->fReSync = FALSE;
}
else
return fCCData;
}
pHwDevExt->dwUserDataBuffer[i++] = 0xB2010000;
while( dwUserReadPtr != dwUserWritePtr )
{
dwData = DVD_ReadDRAM( dwUserReadPtr );
if(dwData == 0x434301F8)
{
MonoOutStr(" CCID ");
fCCData = TRUE;
}
if( (dwData & 0xFFFF0000 ) == 0xFEED0000)
{
MonoOutStr(" Feed ");
pHwDevExt->dwUserDataSize = dwData & 0x00000FFF;
MonoOutStr(" SizeSpecifiedByFirst3Bytes ");
MonoOutULong(pHwDevExt->dwUserDataSize);
}
else
{
pHwDevExt->dwUserDataBuffer[ i] = SwapDWORD(dwData);
i++;
}
// Adjust Data Pointer
dwUserReadPtr += 4L;
if ( dwUserReadPtr >= UserDataBufferEnd)
dwUserReadPtr = UserDataBufferStart;
}
}
DVD_WriteDRAM( USER_DATA_READ, dwUserReadPtr );
dwUserDataBufferSize = i*4 ;
MonoOutStr(" DataReadFromUserBuffer ");
MonoOutULong(dwUserDataBufferSize);
return (fCCData);
}