/*/**************************************************************************** * 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 #include #include #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; iPixWidth == 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); }