535 lines
13 KiB
C
535 lines
13 KiB
C
//******************************************************************************/
|
||
//* *
|
||
//* tc6807af.c - *
|
||
//* *
|
||
//* 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. *
|
||
//* *
|
||
//******************************************************************************/
|
||
|
||
|
||
//
|
||
// TC6907AF.C Digital Copy-Protection for DVD
|
||
//
|
||
/////////////////////////////////////////////////////////////////////
|
||
#ifdef VTOOLSD
|
||
#include <vtoolsc.h>
|
||
#include "monovxd.h"
|
||
#else
|
||
#include "Headers.h"
|
||
#pragma hdrstop
|
||
#endif
|
||
|
||
#include "cl6100.h"
|
||
#include "tc6807af.h"
|
||
#include "fpga.h"
|
||
#include "bmaster.h"
|
||
#include "boardio.h"
|
||
|
||
//-------------------------------------------------------------------
|
||
// TC6907AF REGISTERS DECLARATION
|
||
//-------------------------------------------------------------------
|
||
#define COM 0x00
|
||
#define CNT_1 0x01
|
||
#define CNT_2 0x02
|
||
#define SD_STS 0x03
|
||
#define DEPT_1 0x04
|
||
#define DEPT_2 0x05
|
||
|
||
#define ETKG_0 0x10
|
||
#define ETKG_1 0x11
|
||
#define ETKG_2 0x12
|
||
#define ETKG_3 0x13
|
||
#define ETKG_4 0x14
|
||
#define ETKG_5 0x15
|
||
|
||
#define CHGG_0 0x30
|
||
#define CHGG_1 0x31
|
||
#define CHGG_2 0x32
|
||
#define CHGG_3 0x33
|
||
#define CHGG_4 0x34
|
||
#define CHGG_5 0x35
|
||
#define CHGG_6 0x36
|
||
#define CHGG_7 0x37
|
||
#define CHGG_8 0x38
|
||
#define CHGG_9 0x39
|
||
|
||
#define RSPG_0 0x40
|
||
#define RSPG_1 0x41
|
||
#define RSPG_2 0x42
|
||
#define RSPG_3 0x43
|
||
#define RSPG_4 0x44
|
||
|
||
// COM register bits
|
||
#define END 0x80
|
||
#define ERR 0x40
|
||
|
||
// CNT_1 register bits
|
||
#define RQ1 0x01
|
||
#define RQ2 0x02
|
||
#define ENBEND 0x04
|
||
#define ENBERR 0x08
|
||
#define CLINT 0x10
|
||
|
||
// CNT_2 register bits
|
||
#define THR 0x01
|
||
#define EB1 0x02
|
||
#define EB2 0x04
|
||
#define CDV16 0x08
|
||
#define AJSCK 0x10
|
||
#define SCR1 0x20
|
||
#define SCR2 0x40
|
||
#define SCR3 0x80
|
||
|
||
// Commands
|
||
#define NOP 0x00
|
||
#define DEC_RAND 0x12
|
||
#define DEC_DKY 0x15
|
||
#define DRV_AUTH 0x17
|
||
#define DEC_AUTH 0x18
|
||
#define DEC_DT 0x23
|
||
#define DEC_DTK 0x25
|
||
|
||
//-------------------------------------------------------------------
|
||
// GLOBAL VARIABLES DECLARATION
|
||
//-------------------------------------------------------------------
|
||
DWORD gdwIndex = 0;
|
||
DWORD gdwData = 0;
|
||
|
||
//-------------------------------------------------------------------
|
||
// STATIC FUNCTIONS DECLARATION
|
||
//-------------------------------------------------------------------
|
||
BOOL tc6807af_GetChallengeData( BYTE * CHG );
|
||
BOOL tc6807af_SendChallengeData( BYTE * CHG );
|
||
BOOL tc6807af_GetResponseData( BYTE * RSP );
|
||
BOOL tc6807af_SendResponseData( BYTE * RSP );
|
||
BOOL tc6807af_SendDiskKeyData( BYTE * pBuffer );
|
||
BOOL tc6807af_SendTitleKeyData( BYTE * pBuffer );
|
||
BOOL tc6807af_SetDecryptionMode( BYTE * SR_FLAG );
|
||
BOOL tc6807af_NewCommand( BYTE Command );
|
||
void tc6807af_WriteReg( BYTE byReg, BYTE byValue );
|
||
BYTE tc6807af_ReadReg( BYTE byReg );
|
||
|
||
//
|
||
// TC6807AF_Initialize
|
||
//
|
||
/////////////////////////////////////////////////////////////////////
|
||
BOOL TC6807AF_Initialize( DWORD dwBaseAddress )
|
||
{
|
||
MonoOutStr( " <20><> TC6807AF_Initialize " );
|
||
MonoOutHex( dwBaseAddress );
|
||
|
||
gdwIndex = dwBaseAddress;
|
||
gdwData = dwBaseAddress + 1;
|
||
|
||
//tc6807af_WriteReg( CNT_1, ENBERR | ENBEND | RQ1 | RQ2 );
|
||
|
||
// Step 1.
|
||
tc6807af_WriteReg( CNT_2, 0|CDV16 );
|
||
|
||
// Step 2.
|
||
//tc6807af_WriteReg( CNT_2, AJSCK );
|
||
/*
|
||
tc6807af_WriteReg( CNT_2, 0 );
|
||
tc6807af_WriteReg( CNT_2, AJSCK );
|
||
tc6807af_WriteReg( CNT_2, 0 );
|
||
tc6807af_WriteReg( CNT_2, AJSCK );
|
||
tc6807af_WriteReg( CNT_2, 0 );
|
||
tc6807af_WriteReg( CNT_2, AJSCK );
|
||
tc6807af_WriteReg( CNT_2, 0 );
|
||
tc6807af_WriteReg( CNT_2, AJSCK );
|
||
tc6807af_WriteReg( CNT_2, 0 );
|
||
tc6807af_WriteReg( CNT_2, AJSCK );
|
||
tc6807af_WriteReg( CNT_2, 0 );
|
||
tc6807af_WriteReg( CNT_2, AJSCK );
|
||
tc6807af_WriteReg( CNT_2, 0 );
|
||
tc6807af_WriteReg( CNT_2, AJSCK );
|
||
tc6807af_WriteReg( CNT_2, 0 );
|
||
*/
|
||
// Step 3.
|
||
tc6807af_WriteReg( CNT_1, CLINT );
|
||
|
||
// Step 4.
|
||
tc6807af_WriteReg( DEPT_1, 0 );
|
||
tc6807af_WriteReg( DEPT_2, 0 );
|
||
tc6807af_WriteReg( CNT_2, AJSCK|SCR1 );
|
||
|
||
// Step 5.
|
||
tc6807af_WriteReg( CNT_1, RQ1 | RQ2 );
|
||
tc6807af_WriteReg( CNT_2, AJSCK|SCR1|EB2|EB1|THR );
|
||
|
||
MonoOutStr( " Ķ " );
|
||
return TRUE;
|
||
}
|
||
|
||
//
|
||
// TC6807AF_Reset
|
||
//
|
||
/////////////////////////////////////////////////////////////////////
|
||
BOOL TC6807AF_Reset()
|
||
{
|
||
return TRUE;
|
||
}
|
||
|
||
//
|
||
// TC6807AF_Authenticate
|
||
//
|
||
/////////////////////////////////////////////////////////////////////
|
||
BOOL TC6807AF_Authenticate( WORD wFunction, BYTE * pbyDATA )
|
||
{
|
||
switch ( wFunction )
|
||
{
|
||
case TC6807AF_GET_CHALLENGE:
|
||
return tc6807af_GetChallengeData( pbyDATA );
|
||
|
||
case TC6807AF_SEND_CHALLENGE:
|
||
return tc6807af_SendChallengeData( pbyDATA );
|
||
|
||
case TC6807AF_GET_RESPONSE:
|
||
return tc6807af_GetResponseData( pbyDATA );
|
||
|
||
case TC6807AF_SEND_RESPONSE:
|
||
return tc6807af_SendResponseData( pbyDATA );
|
||
|
||
case TC6807AF_SEND_DISK_KEY:
|
||
return tc6807af_SendDiskKeyData( pbyDATA );
|
||
|
||
case TC6807AF_SEND_TITLE_KEY:
|
||
return tc6807af_SendTitleKeyData( pbyDATA );
|
||
|
||
case TC6807AF_SET_DECRYPTION_MODE:
|
||
return tc6807af_SetDecryptionMode( pbyDATA );
|
||
}
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
|
||
/******************************************************************************/
|
||
/******************* STATIC FUNCTIONS IMPLEMENTATION **************************/
|
||
/******************************************************************************/
|
||
|
||
|
||
//
|
||
// tc6807af_GetChallengeData
|
||
//
|
||
/////////////////////////////////////////////////////////////////////
|
||
BOOL tc6807af_GetChallengeData( BYTE * CHG )
|
||
{
|
||
MonoOutStr( " [DEC_RAND:" );
|
||
|
||
if ( !tc6807af_NewCommand( DEC_RAND ) )
|
||
return FALSE;
|
||
|
||
|
||
CHG[0] = tc6807af_ReadReg( CHGG_0 );
|
||
CHG[1] = tc6807af_ReadReg( CHGG_1 );
|
||
CHG[2] = tc6807af_ReadReg( CHGG_2 );
|
||
CHG[3] = tc6807af_ReadReg( CHGG_3 );
|
||
CHG[4] = tc6807af_ReadReg( CHGG_4 );
|
||
CHG[5] = tc6807af_ReadReg( CHGG_5 );
|
||
CHG[6] = tc6807af_ReadReg( CHGG_6 );
|
||
CHG[7] = tc6807af_ReadReg( CHGG_7 );
|
||
CHG[8] = tc6807af_ReadReg( CHGG_8 );
|
||
CHG[9] = tc6807af_ReadReg( CHGG_9 );
|
||
|
||
MonoOutStr( "] " );
|
||
return TRUE;
|
||
}
|
||
|
||
//
|
||
// tc6807af_SendChallengeData
|
||
//
|
||
/////////////////////////////////////////////////////////////////////
|
||
BOOL tc6807af_SendChallengeData( BYTE * CHG )
|
||
{
|
||
MonoOutStr( " [DEC_AUTH:" );
|
||
|
||
tc6807af_WriteReg( CHGG_0, CHG[0] );
|
||
tc6807af_WriteReg( CHGG_1, CHG[1] );
|
||
tc6807af_WriteReg( CHGG_2, CHG[2] );
|
||
tc6807af_WriteReg( CHGG_3, CHG[3] );
|
||
tc6807af_WriteReg( CHGG_4, CHG[4] );
|
||
tc6807af_WriteReg( CHGG_5, CHG[5] );
|
||
tc6807af_WriteReg( CHGG_6, CHG[6] );
|
||
tc6807af_WriteReg( CHGG_7, CHG[7] );
|
||
tc6807af_WriteReg( CHGG_8, CHG[8] );
|
||
tc6807af_WriteReg( CHGG_9, CHG[9] );
|
||
|
||
if ( !tc6807af_NewCommand( DEC_AUTH ) )
|
||
return FALSE;
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
//
|
||
// tc6807af_GetResponseData
|
||
//
|
||
/////////////////////////////////////////////////////////////////////
|
||
BOOL tc6807af_GetResponseData( BYTE * RSP )
|
||
{
|
||
MonoOutStr( " [GetResponseData" );
|
||
|
||
RSP[0] = tc6807af_ReadReg( RSPG_0 );
|
||
RSP[1] = tc6807af_ReadReg( RSPG_1 );
|
||
RSP[2] = tc6807af_ReadReg( RSPG_2 );
|
||
RSP[3] = tc6807af_ReadReg( RSPG_3 );
|
||
RSP[4] = tc6807af_ReadReg( RSPG_4 );
|
||
|
||
MonoOutStr( "] " );
|
||
return TRUE;
|
||
}
|
||
|
||
//
|
||
// tc6807af_SendResponseData
|
||
//
|
||
/////////////////////////////////////////////////////////////////////
|
||
BOOL tc6807af_SendResponseData( BYTE * RSP )
|
||
{
|
||
MonoOutStr( " [DRV_AUTH:" );
|
||
|
||
tc6807af_WriteReg( RSPG_0, RSP[0] );
|
||
tc6807af_WriteReg( RSPG_1, RSP[1] );
|
||
tc6807af_WriteReg( RSPG_2, RSP[2] );
|
||
tc6807af_WriteReg( RSPG_3, RSP[3] );
|
||
tc6807af_WriteReg( RSPG_4, RSP[4] );
|
||
|
||
if ( !tc6807af_NewCommand( DRV_AUTH ) )
|
||
return FALSE;
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
//
|
||
// tc6807af_SendDiskKeyData
|
||
//
|
||
/////////////////////////////////////////////////////////////////////
|
||
BOOL tc6807af_SendDiskKeyData( BYTE * pBuffer )
|
||
{
|
||
DWORD physAddress;
|
||
DWORD dwTimeout = 10000;
|
||
BYTE byValue;
|
||
int i;
|
||
|
||
MonoOutStr( " [DEC_DKY:" );
|
||
//tc6807af_WriteReg( CNT_1, ENBERR | ENBEND | RQ1 );
|
||
tc6807af_WriteReg( CNT_1, RQ1 );
|
||
tc6807af_WriteReg( CNT_2, SCR1 | EB2 );
|
||
tc6807af_WriteReg( COM, DEC_DKY );
|
||
tc6807af_WriteReg( CNT_1, RQ2|RQ1 );
|
||
tc6807af_WriteReg( CNT_2, SCR1 | EB2|EB1 );
|
||
|
||
MonoOutStr( "DiskKey:" );
|
||
MonoOutULongHex( *((DWORD *)pBuffer) );
|
||
MonoOutStr( " pBuffer:" );
|
||
MonoOutULongHex( (DWORD)pBuffer );
|
||
|
||
// Send one sector
|
||
#ifdef VTOOLSD
|
||
CopyPageTable( (DWORD)pBuffer >> 12, 1, (PVOID*)&physAddress, 0 );
|
||
physAddress = (physAddress & 0xfffff000) + (((DWORD)pBuffer) & 0xfff);
|
||
#else
|
||
physAddress = (DWORD)pBuffer;
|
||
#endif
|
||
|
||
FPGA_Set( FPGA_SECTOR_START );
|
||
|
||
for ( i=0; i<32; i++ )
|
||
{
|
||
if ( !BMA_Send( (DWORD *) (physAddress+i*64), 64 ) )
|
||
return FALSE;
|
||
|
||
dwTimeout = 10000;
|
||
while ( !BMA_Complete() )
|
||
{
|
||
//dvd_SetRequestEnable();
|
||
|
||
if ( !(--dwTimeout) )
|
||
{
|
||
MonoOutStr( " BMA did not complete " );
|
||
return FALSE;
|
||
}
|
||
}
|
||
|
||
dvd_SetRequestEnable();
|
||
}
|
||
|
||
|
||
FPGA_Clear( FPGA_SECTOR_START );
|
||
//tc6807af_WriteReg( CNT_1, CLINT );
|
||
|
||
dwTimeout = 400000;
|
||
while ( --dwTimeout )
|
||
{
|
||
byValue = tc6807af_ReadReg( COM );
|
||
if ( byValue & END )
|
||
{
|
||
//tc6807af_WriteReg( CNT_1, CLINT | RQ1 );
|
||
if ( byValue & ERR )
|
||
{
|
||
//tc6807af_WriteReg( CNT_1, CLINT | RQ1 );
|
||
MonoOutStr( "ERR] " );
|
||
return FALSE;
|
||
}
|
||
MonoOutStr( "End] " );
|
||
return TRUE;
|
||
}
|
||
|
||
}
|
||
|
||
//tc6807af_WriteReg( CNT_1, CLINT | RQ1 );
|
||
MonoOutStr( "Timeout] " );
|
||
return FALSE;
|
||
}
|
||
|
||
//
|
||
// tc6807af_SendTilteKeyData
|
||
//
|
||
/////////////////////////////////////////////////////////////////////
|
||
BOOL tc6807af_SendTitleKeyData( BYTE * ETK )
|
||
{
|
||
DWORD dwTimeout = 100000;
|
||
BYTE byValue;
|
||
|
||
MonoOutStr( " [DEC_DTK:" );
|
||
|
||
tc6807af_WriteReg( ETKG_0, ETK[0] );
|
||
tc6807af_WriteReg( ETKG_1, ETK[1] );
|
||
tc6807af_WriteReg( ETKG_2, ETK[2] );
|
||
tc6807af_WriteReg( ETKG_3, ETK[3] );
|
||
tc6807af_WriteReg( ETKG_4, ETK[4] );
|
||
tc6807af_WriteReg( ETKG_5, ETK[5] );
|
||
|
||
tc6807af_WriteReg( COM, NOP );
|
||
tc6807af_WriteReg( COM, DEC_DTK );
|
||
|
||
while ( --dwTimeout )
|
||
{
|
||
byValue = tc6807af_ReadReg( COM );
|
||
if ( byValue & END )
|
||
{
|
||
if ( byValue & ERR )
|
||
{
|
||
MonoOutStr( "ERR] " );
|
||
return FALSE;
|
||
}
|
||
MonoOutStr( "End] " );
|
||
return TRUE;
|
||
}
|
||
|
||
}
|
||
|
||
MonoOutStr( "Timeout] " );
|
||
return FALSE;
|
||
}
|
||
|
||
//
|
||
// tc6807af_SetDecryptionMode
|
||
//
|
||
/////////////////////////////////////////////////////////////////////
|
||
BOOL tc6807af_SetDecryptionMode( BYTE * SR_FLAG )
|
||
{
|
||
DWORD dwTimeout = 100000;
|
||
BYTE byValue;
|
||
|
||
MonoOutStr( " [DEC_DT:" );
|
||
|
||
if ( *SR_FLAG )
|
||
{
|
||
//tc6807af_WriteReg( CNT_2, EB2 );
|
||
tc6807af_WriteReg( COM, NOP );
|
||
tc6807af_WriteReg( COM, DEC_DT );
|
||
|
||
MonoOutStr( "] " );
|
||
return TRUE;
|
||
|
||
while ( --dwTimeout )
|
||
{
|
||
byValue = tc6807af_ReadReg( COM );
|
||
if ( byValue & END )
|
||
{
|
||
if ( byValue & ERR )
|
||
{
|
||
MonoOutStr( "ERR] " );
|
||
return FALSE;
|
||
}
|
||
MonoOutStr( "End] " );
|
||
return TRUE;
|
||
}
|
||
|
||
}
|
||
|
||
MonoOutStr( "Timeout] " );
|
||
return FALSE;
|
||
}
|
||
else
|
||
{
|
||
tc6807af_WriteReg( CNT_2, SCR1 | EB2 | EB1 | THR );
|
||
MonoOutStr( "Pass Through] " );
|
||
return TRUE;
|
||
}
|
||
|
||
}
|
||
|
||
|
||
/******************************************************************************/
|
||
/******************* LOW LEVEL FUNCTIONS IMPLEMENTATION ***********************/
|
||
/******************************************************************************/
|
||
|
||
//
|
||
// tc6807af_NewCommand
|
||
//
|
||
/////////////////////////////////////////////////////////////////////
|
||
BOOL tc6807af_NewCommand( BYTE Command )
|
||
{
|
||
DWORD dwTimeout = 10000;
|
||
BYTE byValue;
|
||
|
||
tc6807af_WriteReg( COM, Command );
|
||
|
||
if ( (Command == NOP) || (Command == DEC_RAND) )
|
||
return TRUE;
|
||
|
||
while ( --dwTimeout )
|
||
{
|
||
byValue = tc6807af_ReadReg( COM );
|
||
if ( byValue & END )
|
||
{
|
||
if ( byValue & ERR )
|
||
{
|
||
MonoOutStr( "ERR] " );
|
||
return FALSE;
|
||
}
|
||
MonoOutStr( "End] " );
|
||
return TRUE;
|
||
}
|
||
}
|
||
|
||
MonoOutStr( "Timeout] " );
|
||
return FALSE;
|
||
}
|
||
|
||
|
||
//
|
||
// tc6807af_WriteReg
|
||
//
|
||
/////////////////////////////////////////////////////////////////////
|
||
void tc6807af_WriteReg( BYTE byReg, BYTE byValue )
|
||
{
|
||
BRD_WriteByte( gdwIndex, byReg );
|
||
BRD_WriteByte( gdwData, byValue );
|
||
}
|
||
|
||
//
|
||
// tc6807af_ReadReg
|
||
//
|
||
/////////////////////////////////////////////////////////////////////
|
||
BYTE tc6807af_ReadReg( BYTE byReg )
|
||
{
|
||
BRD_WriteByte( gdwIndex, byReg );
|
||
return BRD_ReadByte( gdwData );
|
||
}
|