windows-nt/Source/XPSP1/NT/drivers/video/matrox/mga/mini/vidfile.c
2020-09-26 16:20:57 +08:00

1520 lines
48 KiB
C

/*/****************************************************************************
* name: vidfile.c
*
* description: Calculate video parameters
*
* designed: Gilles-Marie Perron
* last modified: $Author: ctoutant $, $Date: 94/10/24 11:08:23 $
*
* version: $Id: vidfile.c 1.44 94/10/24 11:08:23 ctoutant Exp Locker: ctoutant $
*
* parameters: -
* modifies: -
* calls: -
* returns: -
******************************************************************************/
#include "switches.h"
#include "bind.h"
#include "mtxpci.h" /* pciBoardInfo, PCI_FLAG_ATHENA_REV1 */
#ifdef WINDOWS_NT
bool loadVidPar(dword Zoom, HwModeData *HwMode, HwModeData *DisplayMode);
void calculCrtcParam(void);
byte detectPatchWithGal(void);
void GetMGAConfiguration(volatile byte _Far *, dword*, dword*, dword*);
#if defined(ALLOC_PRAGMA)
#pragma alloc_text(PAGE,loadVidPar)
#pragma alloc_text(PAGE,calculCrtcParam)
#pragma alloc_text(PAGE,detectPatchWithGal)
#endif
//#if defined(ALLOC_PRAGMA)
// #pragma data_seg("PAGE")
//#endif
#endif
#ifndef WINDOWS_NT
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#endif
#include "bind.h"
#include "defbind.h"
#ifndef __DDK_SRC__
#include "sxci.h"
#endif
#include "mgai_c.h"
#include "mgai.h"
#include "mga.h"
#include "vidfile.h"
#if ((!defined (WINDOWS_NT)) || (USE_DDC_CODE))
/*********** DDC CODE ****************/
#include "edid.h"
/*********** DDC CODE ****************/
#endif
#define VCLK_DIVISOR 8
vid vidtab [29] = {{"Pixel_clk", 75000}, /* 0 */
{"H_Front_porch", 24},
{"H_sync", 136},
{"H_back_porch", 144},
{"H_Overscan", 16},
{"H_Visible", 1024}, /* 5 */
{"V_front_porch", 3},
{"V_sync", 6},
{"V_back_porch", 29},
{"V_Overscan", 2},
{"V_visible", 768}, /* 10 */
{"P_width", 8},
{"Overscan_Enable", 0},
{"Interlace_mode_Enable", 0},
{"Start_add_Frame_Buffer", 0},
{"Zoom_factor_x", 1}, /* 15 */
{"Zoom_factor_y", 1},
{"Virtuel_VIDEO_pitch", 1024},
{"ALW", 1},
{"H_blanking_Skew", 0},
{"H_retrace_end_Skew", 0}, /* 20 */
{"Cursor_end_Skew", 0},
{"Cursor_Enable", 0},
{"CRTC_test_Enable", 0},
{"V_IRQ_Enable", 0},
{"Select_5_Refresh_Cycle", 0}, /* 25 */
{"CRTC_reg_0_7_Protect", 0},
{"Hsync_pol", 0},
{"Vsync_pol", 0}
};
ResParamSet ResParam[100] = {
{ 640, 480, 8, 75, 31200, 640, 32, 64, 96, 0, 480, 1, 3, 16, 0, 0, 0, 0, 0 }, { 640, 480, 8, 75, 31200, 640, 32, 64, 96, 0, 480, 1, 3, 16, 0, 0, 0, 0, 0 },
{ 640, 480, 16, 75, 31200, 640, 32, 64, 96, 0, 480, 1, 3, 16, 0, 0, 0, 0, 0 },
{ 640, 480, 24, 75, 31200, 640, 32, 64, 96, 0, 480, 1, 3, 16, 0, 0, 0, 0, 0 },
{ 640, 480, 32, 75, 31200, 640, 32, 64, 96, 0, 480, 1, 3, 16, 0, 0, 0, 0, 0 },
{ 640, 480, 8, 72, 31500, 640, 32, 32, 128, 0, 480, 9, 3, 28, 0, 0, 0, 0, 0 },
{ 640, 480, 16, 72, 31500, 640, 32, 32, 128, 0, 480, 9, 3, 28, 0, 0, 0, 0, 0 },
{ 640, 480, 24, 72, 31500, 640, 32, 32, 128, 0, 480, 9, 3, 28, 0, 0, 0, 0, 0 },
{ 640, 480, 32, 72, 31500, 640, 32, 32, 128, 0, 480, 9, 3, 28, 0, 0, 0, 0, 0 },
{ 640, 480, 8, 60, 25175, 640, 32, 96, 32, 0, 480, 8, 5, 32, 0, 0, 0, 0, 0 },
{ 640, 480, 16, 60, 25175, 640, 32, 96, 32, 0, 480, 8, 5, 32, 0, 0, 0, 0, 0 },
{ 640, 480, 24, 60, 25175, 640, 32, 96, 32, 0, 480, 8, 5, 32, 0, 0, 0, 0, 0 },
{ 640, 480, 32, 60, 25175, 640, 32, 96, 32, 0, 480, 8, 5, 32, 0, 0, 0, 0, 0 },
{ 800, 600, 8, 75, 49500, 800, 32, 64, 160, 1, 600, 1, 3, 21, 0, 0, 0, 1, 1 },
{ 800, 600, 16, 75, 49500, 800, 32, 64, 160, 1, 600, 1, 3, 21, 0, 0, 0, 1, 1 },
{ 800, 600, 24, 75, 49500, 800, 32, 64, 160, 1, 600, 1, 3, 21, 0, 0, 0, 1, 1 },
{ 800, 600, 32, 75, 49500, 800, 32, 64, 160, 1, 600, 1, 3, 21, 0, 0, 0, 1, 1 },
{ 800, 600, 8, 72, 51500, 800, 64, 128, 96, 0, 600, 33, 6, 19, 0, 0, 0, 1, 1 },
{ 800, 600, 16, 72, 51500, 800, 64, 128, 96, 0, 600, 33, 6, 19, 0, 0, 0, 1, 1 },
{ 800, 600, 24, 72, 51500, 800, 64, 128, 96, 0, 600, 33, 6, 19, 0, 0, 0, 1, 1 },
{ 800, 600, 32, 72, 51500, 800, 64, 128, 96, 0, 600, 33, 6, 19, 0, 0, 0, 1, 1 },
{ 800, 600, 8, 60, 40500, 800, 32, 128, 128, 0, 600, 2, 4, 14, 0, 0, 0, 1, 1 },
{ 800, 600, 16, 60, 40500, 800, 32, 128, 128, 0, 600, 2, 4, 14, 0, 0, 0, 1, 1 },
{ 800, 600, 24, 60, 40500, 800, 32, 128, 128, 0, 600, 2, 4, 14, 0, 0, 0, 1, 1 },
{ 800, 600, 32, 60, 40500, 800, 32, 128, 128, 0, 600, 2, 4, 14, 0, 0, 0, 1, 1 },
{ 800, 600, 8, 56, 37800, 800, 32, 128, 128, 0, 600, 2, 4, 14, 0, 0, 0, 1, 1 },
{ 800, 600, 16, 56, 37800, 800, 32, 128, 128, 0, 600, 2, 4, 14, 0, 0, 0, 1, 1 },
{ 800, 600, 24, 56, 37800, 800, 32, 128, 128, 0, 600, 2, 4, 14, 0, 0, 0, 1, 1 },
{ 800, 600, 32, 56, 37800, 800, 32, 128, 128, 0, 600, 2, 4, 14, 0, 0, 0, 1, 1 },
{ 1024, 768, 8, 43, 44900, 1024, 32, 128, 64, 0, 384, 1, 4, 21, 0, 0, 1, 1, 1 },
{ 1024, 768, 16, 43, 44900, 1024, 32, 128, 64, 0, 384, 1, 4, 21, 0, 0, 1, 1, 1 },
{ 1024, 768, 24, 43, 44900, 1024, 32, 128, 64, 0, 384, 1, 4, 21, 0, 0, 1, 1, 1 },
{ 1024, 768, 32, 43, 44900, 1024, 32, 128, 64, 0, 384, 1, 4, 21, 0, 0, 1, 1, 1 },
{ 1024, 768, 8, 75, 78750, 1024, 32, 96, 160, 1, 768, 1, 3, 28, 0, 0, 0, 1, 1 },
{ 1024, 768, 16, 75, 78750, 1024, 32, 96, 160, 1, 768, 1, 3, 28, 0, 0, 0, 1, 1 },
{ 1024, 768, 24, 75, 78750, 1024, 32, 96, 160, 1, 768, 1, 3, 28, 0, 0, 0, 1, 1 },
{ 1024, 768, 32, 75, 78750, 1024, 32, 96, 160, 1, 768, 1, 3, 28, 0, 0, 0, 1, 1 },
{ 1024, 768, 8, 70, 75000, 1024, 32, 128, 160, 0, 768, 3, 6, 21, 0, 0, 0, 0, 0 },
{ 1024, 768, 16, 70, 75000, 1024, 32, 128, 160, 0, 768, 3, 6, 21, 0, 0, 0, 0, 0 },
{ 1024, 768, 24, 70, 75000, 1024, 32, 128, 160, 0, 768, 3, 6, 21, 0, 0, 0, 0, 0 },
{ 1024, 768, 32, 70, 75000, 1024, 32, 128, 160, 0, 768, 3, 6, 21, 0, 0, 0, 0, 0 },
{ 1024, 768, 8, 60, 65000, 1024, 32, 128, 160, 0, 768, 3, 6, 29, 0, 0, 0, 0, 0 },
{ 1024, 768, 16, 60, 65000, 1024, 32, 128, 160, 0, 768, 3, 6, 29, 0, 0, 0, 0, 0 },
{ 1024, 768, 24, 60, 65000, 1024, 32, 128, 160, 0, 768, 3, 6, 29, 0, 0, 0, 0, 0 },
{ 1024, 768, 32, 60, 65000, 1024, 32, 128, 160, 0, 768, 3, 6, 29, 0, 0, 0, 0, 0 },
{ 1152, 882, 8, 75, 111350, 1152, 32, 224, 224, 0, 882, 2, 10, 16, 0, 0, 0, 0, 0 },
{ 1152, 882, 16, 75, 111350, 1152, 32, 224, 224, 0, 882, 2, 10, 16, 0, 0, 0, 0, 0 },
{ 1152, 882, 24, 75, 111350, 1152, 32, 224, 224, 0, 882, 2, 10, 16, 0, 0, 0, 0, 0 },
{ 1152, 882, 32, 75, 111350, 1152, 32, 224, 224, 0, 882, 2, 10, 16, 0, 0, 0, 0, 0 },
{ 1152, 882, 8, 72, 97000, 1152, 97, 128, 95, 0, 882, 4, 8, 20, 0, 0, 0, 0, 0 },
{ 1152, 882, 16, 72, 97000, 1152, 97, 128, 95, 0, 882, 4, 8, 20, 0, 0, 0, 0, 0 },
{ 1152, 882, 24, 72, 97000, 1152, 97, 128, 95, 0, 882, 4, 8, 20, 0, 0, 0, 0, 0 },
{ 1152, 882, 32, 72, 95000, 1152, 64, 128, 68, 0, 882, 28, 8, 39, 0, 0, 0, 0, 0 },
{ 1152, 882, 8, 60, 80500, 1152, 32, 128, 160, 0, 882, 4, 8, 16, 0, 0, 0, 0, 0 },
{ 1152, 882, 16, 60, 80500, 1152, 32, 128, 160, 0, 882, 4, 8, 16, 0, 0, 0, 0, 0 },
{ 1152, 882, 24, 60, 80500, 1152, 32, 128, 160, 0, 882, 4, 8, 16, 0, 0, 0, 0, 0 },
{ 1152, 882, 32, 60, 80500, 1152, 32, 128, 160, 0, 882, 4, 8, 16, 0, 0, 0, 0, 0 },
{ 1280, 1024, 8, 75, 135600, 1280, 32, 128, 256, 1, 1024, 2, 3, 37, 0, 0, 0, 1, 1 },
{ 1280, 1024, 16, 75, 135600, 1280, 32, 128, 256, 1, 1024, 2, 3, 37, 0, 0, 0, 1, 1 },
{ 1280, 1024, 24, 75, 135600, 1280, 32, 128, 256, 1, 1024, 2, 3, 37, 0, 0, 0, 1, 1 },
{ 1280, 1024, 32, 75, 135600, 1280, 32, 128, 256, 1, 1024, 2, 3, 37, 0, 0, 0, 1, 1 },
{ 1280, 1024, 8, 72, 135000, 1280, 64, 128, 288, 0, 1024, 6, 6, 30, 0, 0, 0, 0, 0 }, { 1280, 1024, 8, 72, 135000, 1280, 64, 128, 288, 0, 1024, 6, 6, 30, 0, 0, 0, 0, 0 },
{ 1280, 1024, 16, 72, 135000, 1280, 64, 128, 288, 0, 1024, 6, 6, 30, 0, 0, 0, 0, 0 },
{ 1280, 1024, 24, 72, 135000, 1280, 64, 128, 288, 0, 1024, 6, 6, 30, 0, 0, 0, 0, 0 },
{ 1280, 1024, 32, 72, 135000, 1280, 64, 128, 288, 0, 1024, 6, 6, 30, 0, 0, 0, 0, 0 },
{ 1280, 1024, 8, 60, 110000, 1280, 32, 128, 288, 0, 1024, 3, 3, 26, 0, 0, 0, 0, 0 },
{ 1280, 1024, 16, 60, 110000, 1280, 32, 128, 288, 0, 1024, 3, 3, 26, 0, 0, 0, 0, 0 },
{ 1280, 1024, 24, 60, 110000, 1280, 32, 128, 288, 0, 1024, 3, 3, 26, 0, 0, 0, 0, 0 },
{ 1280, 1024, 32, 60, 110000, 1280, 32, 128, 288, 0, 1024, 3, 3, 26, 0, 0, 0, 0, 0 },
{ 1600, 1200, 8, 72, 185400, 1600, 32, 128, 320, 0, 1200, 4, 18, 16, 0, 0, 0, 0, 0 },
{ 1600, 1200, 16, 72, 185400, 1600, 32, 128, 320, 0, 1200, 4, 18, 16, 0, 0, 0, 0, 0 },
{ 1600, 1200, 24, 72, 185400, 1600, 32, 128, 320, 0, 1200, 4, 18, 16, 0, 0, 0, 0, 0 },
{ 1600, 1200, 32, 72, 185400, 1600, 32, 128, 320, 0, 1200, 4, 18, 16, 0, 0, 0, 0, 0 },
{ 1600, 1200, 8, 60, 156000, 1600, 32, 160, 256, 0, 1200, 10, 8, 48, 0, 0, 0, 0, 0 },
{ 1600, 1200, 16, 60, 156000, 1600, 32, 160, 256, 0, 1200, 10, 8, 48, 0, 0, 0, 0, 0 },
{ 1600, 1200, 24, 60, 156000, 1600, 32, 160, 256, 0, 1200, 10, 8, 48, 0, 0, 0, 0, 0 },
{ 1600, 1200, 32, 60, 156000, 1600, 32, 160, 256, 0, 1200, 10, 8, 48, 0, 0, 0, 0, 0 },
{(word)-1}
};
extern volatile byte _Far* pMgaBaseAddr;
dword crtcTab[NB_CRTC_PARAM];
extern byte iBoard;
extern HwData Hw[NB_BOARD_MAX];
extern char DefaultVidset[];
extern dword ProductMGA[NB_BOARD_MAX];
/* Prototype */
byte detectPatchWithGal(void);
extern char *selectMgaInfoBoard(void);
/****************** definition of exit tab *********************************/
/* */
/*********************** value of registers ********************************/
/* */
/* crtctab[0]= horizontal total */
/* crtctab[1]= horizontal display end */
/* crtctab[2]= horizontal blanking start */
/* crtctab[3]= horizontal blanking end */
/* crtctab[4]= horizontal retrace start */
/* crtctab[5]= horizontal retrace end */
/* crtctab[6]= vertical total */
/* crtctab[7]= overflow */
/* crtctab[8]= preset row scan */
/* crtctab[9]= maximum scanline */
/* crtctab[10]=cursor start */
/* crtctab[11]=cursor end */
/* crtctab[12]=start adrress high */
/* crrctab[13]=start address low */
/* crtctab[14]=cursor position high */
/* crtctab[15]=cursor position low */
/* crtctab[16]=vertical retrace start */
/* crtctab[17]=vertical retrace end */
/* crtctab[18]=vertical display enable end */
/* crtctab[19]=offset */
/* crtctab[20]=underline location */
/* crtctab[21]=vertical blanking start */
/* crtctab[22]=vertical blanking end */
/* crtctab[23]=mode control */
/* crtctab[24]=line compare */
/* crtctab[25]=cpu page select */
/* crtctab[26]=crtc extended address register */
/* crtctab[27]=32k video ram page select register */
/* crtctab[28]=interlace support register */
/* crtctab[29]=automatic line wrap */
/* crtctab[30]=pixel clock */
/* crtctab[31]=video delay */
/* crtctab[32]=Hsync polarite */
/* crtctab[33]=sync delay of dub_ctl register */
/* */
/***************************************************************************/
/************************************************************************/
/*/
* Name: loadVidPar()
*
* synopsis:
*
* bugs:
* designed:
* reviewed:
* last modified:
*
* parameters: (char *vidFile);
* uses:
*
* calls: calculCrtcParam();
*
* returns: mtxOK
* mtxFAIL
*************************************************************************/
bool loadVidPar(dword Zoom, HwModeData *HwMode, HwModeData *DisplayMode)
{
general_info *genInfo;
Vidparm *vidParm;
word TmpRes, ZoomIndex, ZoomVal;
Vidset *pVidset = (Vidset *)0;
word NbVidParam, i;
ZoomVal = (word)(Zoom & 0x0000ffff);
#if ((!defined (WINDOWS_NT)) || (USE_DDC_CODE))
/*********** DDC CODE ****************/
if ( SupportDDC )
{
/*** Find video parameters with the highest refresh rate (see vesavid.h) ***/
pVidset = NULL;
for (i=0; VesaParam[i].DispWidth != (word)-1 ; i++)
{
if( VesaParam[i].DispWidth == DisplayMode->DispWidth && VesaParam[i].Support )
{
pVidset = &(VesaParam[i].VideoSet);
break;
}
}
if( pVidset == NULL )
return(mtxFAIL);
}
/*********** DDC CODE ****************/
else
#endif
{
if (Zoom & 0xff000000)
{
pVidset = NULL;
for (i=0; ResParam[i].DispWidth != (word)-1 ; i++)
{
if ((ResParam[i].DispWidth == DisplayMode->DispWidth) &&
(ResParam[i].PixDepth == DisplayMode->PixWidth) &&
(ResParam[i].RefreshRate == (word)((Zoom >> 24) & 0x000000ff)))
{
pVidset = &(ResParam[i].VideoSet);
break;
}
}
if (pVidset == NULL)
return(mtxFAIL);
}
else
{
switch(Zoom & 0xff)
{
case 2: ZoomIndex = 1; break;
case 4: ZoomIndex = 2; break;
default: ZoomIndex = 0; break;
}
/*** According to Board#, Resolution and PixWidth: Determine pVidset ***/
/* ChT if no paramters for this card then default parameters */
if ( !(genInfo = (general_info *)selectMgaInfoBoard()) ||
(genInfo->NumVidparm < 0)
)
{
#ifdef PRINT
printf("No info for this board in mga.inf file\n");
printf("Please run Setup\n");
#endif
vidParm = (Vidparm *)( DefaultVidset + sizeof(header) + sizeof(general_info));
NbVidParam = ( (general_info *)( DefaultVidset + sizeof(header)))->NumVidparm;
}
else
{
vidParm = (Vidparm *)( (char *)genInfo + sizeof(general_info));
NbVidParam = genInfo->NumVidparm;
}
/* Determine TmpRes for compatibility with spec mga.inf */
switch (DisplayMode->DispWidth)
{
case 640:
if (DisplayMode->DispType & 0x02)
TmpRes = RESNTSC;
else
TmpRes = RES640;
break;
case 768:
TmpRes = RESPAL;
break;
case 800:
TmpRes = RES800;
break;
case 1024:
TmpRes = RES1024;
break;
case 1152:
TmpRes = RES1152;
break;
case 1280:
TmpRes = RES1280;
break;
case 1600:
TmpRes = RES1600;
break;
}
for (i=0; i<NbVidParam; i++)
{
if ( vidParm[i].Resolution == TmpRes &&
vidParm[i].PixWidth == (DisplayMode->PixWidth == 24 ? 32:DisplayMode->PixWidth)
)
{
pVidset = &(vidParm[i].VidsetPar[ZoomIndex]);
break;
}
}
if (!pVidset)
{
#ifdef PRINT
printf("Video parameter not found in mga.inf");
#endif
return mtxFAIL;
}
/*** If there is no video parameter in file mga.inf for zoomming > 1
(the first item = -1) then we keep video parameters for zoom = 1 ***/
if ((pVidset->PixClock == (long)-1) && (ZoomVal > 1))
pVidset = &(vidParm[i].VidsetPar[0]);
}
} /* else - Support DDC */
/*** Transfer video parametres towards array vidtab[] ***/
if (ZoomVal == 0) {
VideoDebugPrint ((0, "Division by zero (ZoomVal == 0) may occur!!"));
}
else
vidtab[0].valeur = (unsigned long)pVidset->PixClock / ZoomVal;
vidtab[1].valeur = (unsigned long)pVidset->HFPorch;
vidtab[2].valeur = (unsigned long)pVidset->HSync;
vidtab[3].valeur = (unsigned long)pVidset->HBPorch;
vidtab[4].valeur = (unsigned long)pVidset->HOvscan;
vidtab[5].valeur = (unsigned long)pVidset->HDisp;
vidtab[6].valeur = (unsigned long)pVidset->VFPorch;
vidtab[7].valeur = (unsigned long)pVidset->VSync;
vidtab[8].valeur = (unsigned long)pVidset->VBPorch;
vidtab[9].valeur = (unsigned long)pVidset->VOvscan;
vidtab[10].valeur = (unsigned long)pVidset->VDisp;
vidtab[11].valeur = DisplayMode->PixWidth;
vidtab[12].valeur = (unsigned long)pVidset->OvscanEnable;
vidtab[13].valeur = (unsigned long)pVidset->InterlaceEnable;
vidtab[14].valeur = Hw[iBoard].YDstOrg; /* Start address */
/* PACK PIXEL, CRTC en 32 bit et TITAN en 8 bits
donc, YDstOrg transfome en byte
*/
if (DisplayMode->PixWidth == 24)
vidtab[14].valeur >>= 2;
vidtab[15].valeur = ZoomVal; /* Zoom factor X */
vidtab[16].valeur = ZoomVal; /* Zoom factor Y */
vidtab[17].valeur = HwMode->FbPitch; /* Virtual video pitch */
if ( (DisplayMode->FbPitch != HwMode->FbPitch) || (ZoomVal > 1) ||
(DisplayMode->DispType & 0x01) ||
(ProductMGA[iBoard] == MGA_PCI_4M) )
vidtab[18].valeur = 0; /* ALW Non-Automatic Line Wrap */
else
vidtab[18].valeur = 1;
if( detectPatchWithGal() )
vidtab[18].valeur = 0; /* ALW Non-Automatic Line Wrap */
vidtab[27].valeur = (unsigned long)pVidset->HsyncPol;
vidtab[28].valeur = (unsigned long)pVidset->VsyncPol;
return(mtxOK);
}
/************************************************************************/
/* */
/* Translate the CTRC value in MGA registers value... */
/* */
/************************************************************************/
void calculCrtcParam(void)
{
/*declarations-------------------------------------------------------------*/
unsigned long bs, be;
unsigned long h_front_p,hbskew,hretskew,h_sync,h_back_p,h_over;
unsigned long h_vis,h_total,v_vis,v_over,v_front_p,v_sync,v_back_p,vert_t;
unsigned long start_add_f,virt_vid_p,v_blank;
unsigned char v_blank_e,rline_c,cpu_p,page_s,alw,p_width;
unsigned long mux_rate,ldclk_en_dotclk;
int over_e,hsync_pol,div_1024,int_m;
int vclkhtotal,vclkhvis,vclkhsync,vclkhover,vclkhbackp,vclkhblank,vclkhfrontp;
int x_zoom,y_zoom;
int Cur_e,Crtc_tst_e,cur_e_sk,e_v_int,sel_5ref,crtc_reg_prt,i;
long rep_ge,nb_vclk_hfront_p,nb_vclk_hblank,delai,delai2,delai3,delai4;
/* long gclk; */
long vclk_divisor,pixel_clk;
int flagDelay3=0,flagDelay4=0;
long delayTab[4]={5000,11000,24000,28000}; /* for the value of delays */
long delayTab_A[6]={3000, 4000, 5000,11000,24000,28000}; /* for the value of delays */
/* of register crtc_ctrl of the titan */
/* structure for horizontal blanking end register -------------------------*/
union{
struct {unsigned char pos :5;
unsigned char skew:2;
unsigned char res :1;
}f;
unsigned char all;
} hor_blk_e;
/* structure for horizontal retrace end register----------------------------*/
union{
struct {unsigned char pos :5;
unsigned char skew:2;
unsigned char res :1;
}f;
unsigned char all;
} hor_ret;
/* structure for the calculation of the horizontal blank end position-------*/
/* since the last bit goes in the horizontal retrace end register ----------*/
union{
struct {unsigned char horz_blank_e :5;
unsigned char horz_ret :1;
unsigned char unused :2;
}f;
unsigned char all;
} hor_blk_a;
/* structure for the calculation of the vertical total since the first 7 bit go----*/
/* in the vertical total register and 8 and 9 go in the overflow register-*/
union{
struct {unsigned long vert_t0_7 :8;
unsigned long vert_t8 :1;
unsigned long vert_t9 :1;
unsigned long unused :22;
}f;
unsigned long all;
} v_total;
/* structure for the overflow register--------------------------------------*/
union{
struct {unsigned char r0 :1;
unsigned char r1 :1;
unsigned char r2 :1;
unsigned char r3 :1;
unsigned char r4 :1;
unsigned char r5 :1;
unsigned char r6 :1;
unsigned char r7 :1;
}f;
unsigned char all;
} r_overf;
/* structure for the maximum scan line register-----------------------------*/
union{
struct {unsigned char maxsl :5;
unsigned char v_blank_9 :1;
unsigned char line_c :1;
unsigned char line_doub_e :1;
}f;
unsigned char all;
} r_maxscanl;
/* structure for the cursor start register----------------------------------*/
union{
struct {unsigned char curstart :5;
unsigned char cur_e :1;
unsigned char res :1;
unsigned char crtc_tst_e :1;
}f;
unsigned char all;
} r_cursor_s;
/* structure for the cursor end register------------------------------------*/
union{
struct {unsigned char curend :5;
unsigned char cur_sk :2;
unsigned char res :1;
}f;
unsigned char all;
} r_cursor_e;
/* structure for the calculation of the vertical retrace start register------*/
/* the 7 least significant bits go in the register and the other 2 */
/* go in the overflow register */
union{
struct {unsigned long bit0_7 :8;
unsigned long bit8 :1;
unsigned long bit9 :1;
}f;
unsigned long all;
} rvert_ret_s;
/* structure for the vertical retrace end register -------------------------*/
union{
struct {unsigned char bit0_3 :4;
unsigned char cl :1;
unsigned char e_vi :1;
unsigned char sel_5ref :1;
unsigned char reg_prot :1;
}f;
unsigned char all;
} rvert_ret_e;
/* structure for the calculation of the vertical display enable end---------*/
union{
struct {unsigned long bit0_7 :8;
unsigned long bit8 :1;
unsigned long bit9 :1;
}f;
unsigned long all;
} v_disp_e;
/* structure for the calculation of the vertical blanking start-------------*/
union{
struct {unsigned long bit0_7 :8;
unsigned long bit8 :1;
unsigned long bit9 :1;
}f;
unsigned long all;
} v_blank_s;
/* structure of the mode control register ----------------------------------*/
union{
struct {unsigned char r0 :1;
unsigned char r1 :1;
unsigned char r2 :1;
unsigned char r3 :1;
unsigned char r4 :1;
unsigned char r5 :1;
unsigned char r6 :1;
unsigned char r7 :1;
}f;
unsigned char all;
} r_mode;
/* structure of the crtc extended add register------------------------*/
union{
struct {unsigned char crtcadd :2;
unsigned char crtccur :2;
unsigned char crtc_add_e :1;
unsigned char aux_cl :1;
unsigned char dip_sw_e :1;
unsigned char irq_e :1;
}f;
unsigned char all;
} r_crtc_ext;
/*structure of the interlace support register--------------------------*/
union{
struct {unsigned char crtcadd :4;
unsigned char seq_vid :1;
unsigned char port :1;
unsigned char m_int :1;
unsigned char hr_16 :1;
}f;
unsigned char all;
} r_int_s;
/* gclk=25.0e-9; */
vclk_divisor=VCLK_DIVISOR;
/* variable defined for the entry table-------------------------------- */
pixel_clk =vidtab[0].valeur * 1000;
h_front_p =vidtab[1].valeur;
h_sync =vidtab[2].valeur;
h_back_p =vidtab[3].valeur;
h_over =vidtab[4].valeur;
h_vis =vidtab[5].valeur;
v_front_p =vidtab[6].valeur;
v_sync =vidtab[7].valeur;
v_back_p =vidtab[8].valeur;
v_over =vidtab[9].valeur;
v_vis =vidtab[10].valeur;
p_width =(unsigned char)vidtab[11].valeur;
over_e =vidtab[12].valeur;
int_m =vidtab[13].valeur;
start_add_f =vidtab[14].valeur;
x_zoom =vidtab[15].valeur;
y_zoom =vidtab[16].valeur;
virt_vid_p =vidtab[17].valeur;
alw =(unsigned char)vidtab[18].valeur;
hbskew =vidtab[19].valeur;
hretskew =vidtab[20].valeur;
cur_e_sk =vidtab[21].valeur;
Cur_e =vidtab[22].valeur;
Crtc_tst_e =vidtab[23].valeur;
e_v_int =vidtab[24].valeur;
sel_5ref =vidtab[25].valeur;
crtc_reg_prt =vidtab[26].valeur;
hsync_pol =vidtab[27].valeur;
if (p_width == 24) /* Pack Pixel */
{
h_front_p = (h_front_p * 3 ) >> 2;
h_sync = (h_sync * 3 ) >> 2;
h_back_p = (h_back_p * 3 ) >> 2;
h_over = (h_over * 3 ) >> 2;
h_vis = (h_vis * 3 ) >> 2;
if ( (h_front_p % 32) ) h_front_p += 32 - (h_front_p % 32);
if ( (h_sync % 32) ) h_sync += 32 - (h_sync % 32);
if ( (h_back_p % 32) ) h_back_p += 32 - (h_back_p % 32);
}
/*----------------calculation of reg htotal --------------------------------*/
h_total=h_vis+h_front_p+h_sync+h_back_p;
#ifdef NO_FLOAT
vclkhtotal= (((h_total/VCLK_DIVISOR)*10)+5)/10;
#else
vclkhtotal=h_total/VCLK_DIVISOR+0.5;
#endif
crtcTab[0]=(vclkhtotal/x_zoom)-5;
/* in pack pixel, the number of LCLKs in the total horizontal line
(active + blanked) must be a multiple of the number of LCLKs
per pixel group.
*/
if ((p_width == 24) && ((crtcTab[0]+5) % 3 )) /* Pack Pixel */
{
vclkhtotal += (3 - ((crtcTab[0]+5) % 3)) * x_zoom;
crtcTab[0] += 3 - ((crtcTab[0]+5) % 3);
}
/* PACK PIXEL, temporary PATCH */
/*----------------calculation of the horizontal display enable end reg -----*/
#ifdef NO_FLOAT
vclkhvis=(((h_vis/VCLK_DIVISOR)*10)+5)/10;
#else
vclkhvis=h_vis/VCLK_DIVISOR+0.5;
#endif
crtcTab[1]=(vclkhvis/x_zoom)-1;
/*----------------calculation of the horizontal blanking start register-----*/
if(detectPatchWithGal() == 0)
{
if (h_over>0)
{
if (h_over<(VCLK_DIVISOR/2))
vclkhover=1*over_e;
else
#ifdef NO_FLOAT
vclkhover=((((h_over/VCLK_DIVISOR)*10)+5)/10)*over_e;
#else
vclkhover=(h_over/VCLK_DIVISOR+0.5)*over_e;
#endif
}
else
vclkhover=0;
/* Create overscan to bypass a problem in the bank switch */
/* with old revision of TVP3026 */
crtcTab[2]=((vclkhvis+vclkhover)/x_zoom)-1;
}
else
{
crtcTab[2] = crtcTab[1] - 1; /* See DAT #??? */
vclkhover=0;
}
/*-----------calculation of horizontal blanking end register----------------*/
#ifdef NO_FLOAT
vclkhfrontp=(((h_front_p/VCLK_DIVISOR)*10)+5)/10;
vclkhsync=(((h_sync/VCLK_DIVISOR)*10)+5)/10;
vclkhbackp=(((h_back_p/VCLK_DIVISOR)*10)+5)/10;
#else
vclkhfrontp=h_front_p/VCLK_DIVISOR+0.5;
vclkhsync=h_sync/VCLK_DIVISOR+0.5;
vclkhbackp=h_back_p/VCLK_DIVISOR+0.5;
#endif
vclkhblank=vclkhfrontp+vclkhbackp+vclkhsync-(2*vclkhover*over_e);
hor_blk_a.all=((vclkhvis+vclkhover+vclkhblank)/x_zoom)-2;
bs = crtcTab[2];
be = hor_blk_a.all + 1;
if (!((0x40 > bs) & (0x40 < be) ||
(0x80 > bs) & (0x80 < be) ||
(0xc0 > bs) & (0xc0 < be)))
hor_blk_a.all = 0;
if (detectPatchWithGal() == 0)
hor_blk_e.f.pos=hor_blk_a.f.horz_blank_e;
else
hor_blk_e.f.pos=(vclkhtotal/x_zoom)-2;
hor_blk_e.f.skew=(unsigned char)hbskew;
hor_blk_e.f.res=0;
crtcTab[3]=hor_blk_e.all;
/*----------calculation of the horizontal retrace start register----------*/
crtcTab[4]=((vclkhvis+vclkhfrontp)/x_zoom)-1;
/*---------------calculation of the horizontal retrace end register---------*/
hor_ret.f.pos=((vclkhvis+vclkhfrontp+vclkhsync)/x_zoom)-1;
hor_ret.f.skew=(unsigned char)hretskew;
hor_ret.f.res=hor_blk_a.f.horz_ret;
if(detectPatchWithGal() == 0)
hor_ret.f.res=hor_blk_a.f.horz_ret;
else
hor_ret.f.res=(unsigned char)(crtcTab[0]+3) >> 5;
crtcTab[5]=hor_ret.all;
/*--------------calculation of the vertical total register ----------------*/
vert_t=v_vis+v_front_p+v_sync+v_back_p;
div_1024=(vert_t>1023) ? 2 : 1;
v_total.all=vert_t/div_1024-2;
crtcTab[6]=v_total.f.vert_t0_7;
/*------------- preset row scan register -----------------------------------*/
crtcTab[8]=0;
/*----------------calculation of the cursor start register------------------*/
r_cursor_s.f.curstart=0;
r_cursor_s.f.cur_e=~Cur_e;
r_cursor_s.f.res=0;
r_cursor_s.f.crtc_tst_e=(byte)Crtc_tst_e;
crtcTab[10]=r_cursor_s.all;
/*----------------calculation of the cursor end register -------------------*/
r_cursor_e.f.curend=0;
r_cursor_e.f.cur_sk=(byte)cur_e_sk;
r_cursor_e.f.res=0;
crtcTab[11]=r_cursor_e.all;
/*----------------calculation of the add start add high register -----------*/
start_add_f = start_add_f / 8;
crtcTab[12]=start_add_f/256;
/*-----------------calculation of the add start add low register -----------*/
crtcTab[13]=start_add_f;
/*----------------- cursor position high register --------------------------*/
crtcTab[14]=0;
/*----------------- cursor position low register ---------------------------*/
crtcTab[15]=0;
/*------------------calculation of the vertical retrace start register------*/
rvert_ret_s.all=((v_vis+v_front_p)/div_1024)-1;
crtcTab[16]=rvert_ret_s.f.bit0_7;
/*-------------- calculation of the vertical retrace end register ----------*/
rvert_ret_e.f.bit0_3=(unsigned char)(v_vis+v_front_p+v_sync)/div_1024-1;
rvert_ret_e.f.cl=1;
rvert_ret_e.f.e_vi=(byte)e_v_int;
rvert_ret_e.f.sel_5ref=(byte)sel_5ref;
rvert_ret_e.f.reg_prot=(byte)crtc_reg_prt;
crtcTab[17]=rvert_ret_e.all;
/*--------------calculation of the vertical display enable register --------*/
v_disp_e.all=v_vis/div_1024-1;
crtcTab[18]=v_disp_e.f.bit0_7;
/*--------------calculation of the offset register -------------------------*/
crtcTab[19]=((virt_vid_p/VCLK_DIVISOR)+(virt_vid_p*int_m/VCLK_DIVISOR))/2;
if (p_width == 24) /* Pack Pixel */
crtcTab[19] = (crtcTab[19] * 3) >> 2;
/*------------------ under line location register --------------------------*/
crtcTab[20]=0;
/*-----------calculation of the vertical blanking start register ----------*/
v_blank_s.all=(v_vis+(v_over*over_e))/div_1024-1;
crtcTab[21]=v_blank_s.f.bit0_7;
/*-----------calculation of the vertical blanking end register ------------*/
v_blank=v_back_p+v_sync+v_front_p-(2*v_over*over_e);
v_blank_e=(unsigned char)(
(v_vis+(v_over*over_e)+v_blank-((v_over*over_e>0) ? 0 : 1))/div_1024-1);
crtcTab[22]=v_blank_e;
/*-------------- mode control register -------------------------------------*/
r_mode.f.r0=0;
r_mode.f.r1=0;
r_mode.f.r2=div_1024==2 ? 1 : 0 ;
r_mode.f.r3=0;
r_mode.f.r4=0;
r_mode.f.r5=0;
r_mode.f.r6=1;
r_mode.f.r7=1;
crtcTab[23]=r_mode.all;
/*----------- line compare register ----------------------------------------*/
#ifdef WINDOWS_NT
rline_c=0xFF;
#else
rline_c=-1;
#endif
crtcTab[24]=rline_c;
/*-----------calculation of the maximum scan line register -----------------*/
r_maxscanl.f.maxsl=(y_zoom==1) ? 0 : y_zoom-1;
r_maxscanl.f.v_blank_9=(unsigned char)v_blank_s.f.bit9;
r_maxscanl.f.line_c=1;
r_maxscanl.f.line_doub_e=0;
crtcTab[9]=r_maxscanl.all;
/*-------------- overflow register -----------------------------------------*/
r_overf.f.r0=(unsigned char)v_total.f.vert_t8;
r_overf.f.r1=(unsigned char)v_disp_e.f.bit8;
r_overf.f.r2=(unsigned char)rvert_ret_s.f.bit8;
r_overf.f.r3=(unsigned char)v_blank_s.f.bit8;
r_overf.f.r4=1;
r_overf.f.r5=(unsigned char)v_total.f.vert_t9;
r_overf.f.r6=(unsigned char)v_disp_e.f.bit9;
r_overf.f.r7=(unsigned char)rvert_ret_s.f.bit9;
crtcTab[7]=r_overf.all;
/*------------ cpu page select register ------------------------------------*/
cpu_p=0;
crtcTab[25]=cpu_p;
/*------------ crtc extended address register ------------------------------*/
r_crtc_ext.f.crtcadd=0;
r_crtc_ext.f.crtccur=0;
r_crtc_ext.f.crtc_add_e=1;
r_crtc_ext.f.aux_cl=0;
r_crtc_ext.f.dip_sw_e=0;
r_crtc_ext.f.irq_e=1;
crtcTab[26]=r_crtc_ext.all;
/*------------ 32k video ram page select register -----------------*/
page_s=0;
crtcTab[27]=page_s;
/*----------- interlace support register--------------------------*/
r_int_s.f.crtcadd=0;
r_int_s.f.seq_vid=0;
r_int_s.f.port=0;
r_int_s.f.m_int=(byte)int_m;
r_int_s.f.hr_16=0;
crtcTab[28]=r_int_s.all;
/*------------other arguments entered in the table------------------------*/
crtcTab[29]=alw;
crtcTab[30]=pixel_clk;
crtcTab[32]=hsync_pol;
/*************************************************************************/
/* */
/* calculation of video delay for the crtc_ctrl register */
/* */
/*************************************************************************/
rep_ge=(37*25*(pixel_clk/1000000)) / vclk_divisor;
nb_vclk_hfront_p= (h_front_p*1000) / (vclk_divisor * x_zoom);
nb_vclk_hblank=( ((h_front_p+h_sync+h_back_p)*1000) / (VCLK_DIVISOR) / x_zoom);
delai=nb_vclk_hfront_p-1000;
delai2=rep_ge-625;
delai3=nb_vclk_hblank-rep_ge-2000;
delai4=((nb_vclk_hblank+1000)/2)-3000;
/*** BEN ajout ***/
crtcTab[31]=0x00;
if ( (Hw[iBoard].ProductRev >> 4) == 0 ) /* TITAN */
{
for (i=0;i<4;i++)
{
if (delayTab[i]>=delai)
{
if (delayTab[i]>=delai2)
{
if (delayTab[i]<=delai3)
{
/*** The fourth was temporarily eliminated ***/
/* if (delayTab[i]<=delai4) */
/* { */
if (delayTab[i]==28000)
{
crtcTab[31]=0x03;
break;
}
else if (delayTab[i]==24000)
{
crtcTab[31]=0x02;
break;
}
else if (delayTab[i]==11000)
{
crtcTab[31]=0x01;
break;
}
else
{
crtcTab[31]=0x00;
break;
}
/* } */
}
}
}
}
}
else /* 2 video delay add for atlas and I suppose,for newest */
{ /* variation of titan they have the same video delay */
for (i=0;i<6;i++)
{
if (delayTab_A[i]>=delai)
{
if (delayTab_A[i]>=delai2)
{
if (delayTab_A[i]<=delai3)
{
if (delayTab_A[i]==28000)
{
crtcTab[31]=0x3;
break;
}
else if (delayTab_A[i]==24000)
{
crtcTab[31]=0x2;
break;
}
else if (delayTab_A[i]==11000)
{
crtcTab[31]=0x1;
break;
}
else if (delayTab_A[i]==5000)
{
crtcTab[31]=0x0;
break;
}
else if (delayTab_A[i]==4000)
{
crtcTab[31]=0x5;
flagDelay4=1;
break;
}
else if (delayTab_A[i]==3000)
{
crtcTab[31]=0x4;
flagDelay3=1;
continue;
}
}
}
}
}
}
if ( flagDelay3 && flagDelay4 )
crtcTab[31]=0x5; /* if we are videodelay 3 and 4 they respect 3 rules */
/***************************************************************************/
/* */
/* calcul hsync delay for the register dub_ctl for the field hsync_del */
/* */
/***************************************************************************/
switch (p_width)
{
case 8:
mux_rate=ldclk_en_dotclk=4;
break;
case 16:
mux_rate=ldclk_en_dotclk=2;
break;
/* PACK PIXEL add cas 24 */
case 32:
case 24:
mux_rate=ldclk_en_dotclk=1;
break;
}
switch (Hw[iBoard].DacType)
{
case BT485:
case PX2085:
/*********************************/
/* For BT485 */
/* */
/* syncdel=1 ldclk expressed in */
/* dotclock + 7 dotclock */
/* --------------------- */
/* (muxrate) */
/* */
/* syncdel= a whole value */
/* and rounded */
/* */
/* muxrate= ( 8bpp=4:1) */
/* = (16bpp=2:1) */
/* = (32bpp=1:1) */
/* */
/* */
/*********************************/
crtcTab[33]=((ldclk_en_dotclk+7)*100/mux_rate+50)/100;
break;
case VIEWPOINT: /*********************************/
/* */
/* For VIEWPOINT */
/* */
/* syncdel=2 ldclk expressed in */
/* dotclock + 14 dotclock*/
/* --------------------- */
/* (muxrate) */
/* */
/* syncdel= a whole value */
/* and rounded */
/* */
/* muxrate= ( 8bpp=4:1) */
/* = (16bpp=2:1) */
/* = (32bpp=1:1) */
/* */
/* */
/*********************************/
crtcTab[33]=02/*((ldclk_en_dotclk*2 + 14)*100/(mux_rate*2)+50)/100*/;
break;
case TVP3026:
crtcTab[33]=0;
break;
#ifdef SCRAP
case BT481:
crtcTab[33]=02;
break;
#endif
default:
crtcTab[33]=02;
break;
}
}
/************************************************************************/
/*/
* Name: getAthenaRevision
*
* synopsis: try to find the silicone revision of athena chip
*
*
* returns: revision : -1 - Unknow or not a athena chip
*/
/* --------------------------- D.A.T. GEN0?? ---------------------------*/
/* Strap nomuxes block8 tram Athena rev| Type de ram */
/* 0 0 0 2 |4Mbit (8-bit blk node) */
/* 0 0 1 2 | " " " */
/* 0 1 0 2 |4Mbit (4-bit blk node) */
/* 0 1 1 1 |2Mbit (4-bit blk node) */
/* | */
/* 1 0 0 1 |4Mbit (8-bit blk node) */
/* 1 0 1 1 | " " " */
/* 1 1 0 1 |4Mbit (4-bit blk node) */
/* 1 1 1 2 |2Mbit (4-bit blk node) */
/*----------------------------------------------------------------------*/
word getAthenaRevision(dword dst0, dword dst1)
{
byte _block8, _tram, _nomuxes;
word rev = 2;
_block8 = (dst0 & TITAN_DST0_BLKMODE_M) != 0;
_tram = (dst1 & TITAN_DST1_TRAM_M) != 0;
_nomuxes = (dst1 & TITAN_DST1_NOMUXES_M) != 0;
/* check if athena chip */
if( ((Hw[iBoard].ProductRev >> 4) & 0x0000000f) != ATHENA_CHIP)
return (word) -1;
if ( Hw[iBoard].DacType == TVP3026 )
{
if (_block8 && _tram) /* IMP+ /P */
{
rev = _nomuxes ? 2 : 1;
}
else
{
rev = _nomuxes ? 1 : 2;
}
}
else
{
if ( Hw[iBoard].VGAEnable )
rev = pciBoardInfo & PCI_FLAG_ATHENA_REV1 ? 1 : 2;
else
rev = 2;
}
return rev;
}
/************************************************************************/
/*/
* Name: detectPatchWithGal
*
* synopsis: Detect if the board has the patch that fixes the bug
* with SOE (See DAT on missing pixel in the bank switch).
*
*
* returns: byte : mtxOK - the board has the patch.
* mtxFAIL - it hasn't
*/
byte detectPatchWithGal(void)
{
byte result=0;
dword TramDword;
/* general_info *genInfo; */
dword Dst0, Dst1;
dword InfoHardware;
if ( Hw[iBoard].DacType != TVP3026 )
return mtxFAIL; /* GAL in use on TVP3026 only */
if ((Hw[iBoard].ProductType & 0x0f) == BOARD_MGA_RESERVED)
return mtxFAIL; /* Always rev 2 */
/*------ Strap added in ATHENA For max clock dac support ----*/
GetMGAConfiguration(pMgaBaseAddr, &Dst0, &Dst1, &InfoHardware);
if ( Dst1 & TITAN_DST1_ABOVE1280_M )
return mtxFAIL; /* no gal on this board */
if ( getAthenaRevision(Dst0, Dst1) == 2)
return mtxFAIL; /* No gal on rev 2 */
mgaReadDWORD(*(pMgaBaseAddr+TITAN_OFFSET+TITAN_OPMODE),TramDword);
TramDword &= TITAN_TRAM_M;
/** The GAL is present on Rev2 or higher board with bit TRAM at 0 and
on board with bit TRAM at 1 (/P4) **/
if( (((Hw[iBoard].ProductRev & 0xf) >= 2) && !TramDword) || TramDword)
result = mtxOK;
else
result = mtxFAIL;
return(result);
}
word ConvBitToFreq (word BitFreq)
{
word result;
// bit 0: 43 Hz interlaced
// bit 1: 56 Hz
// bit 2: 60 Hz
// bit 3: 66 Hz
// bit 4: 70 Hz
// bit 5: 72 Hz
// bit 6: 75 Hz
// bit 7: 76 Hz
// bit 8: 80 Hz
// bit 9: 85 Hz
// bit 10: 90 Hz
// bit 11: 100 Hz
// bit 12: 120 Hz
switch (BitFreq)
{
case 0:
result = 43;
break;
case 1:
result = 56;
break;
case 2:
result = 60;
break;
case 3:
result = 66;
break;
case 4:
result = 70;
break;
case 5:
result = 72;
break;
case 6:
result = 75;
break;
case 7:
result = 76;
break;
case 8:
result = 80;
break;
case 9:
result = 85;
break;
case 10:
result = 90;
break;
case 11:
result = 100;
break;
case 12:
result = 120;
default:
result = 0;
break;
}
return(result);
}