/*/**************************************************************************** * name: mtxinit.c * * description: Routines to initialise MGA board * * designed: Benoit Leblanc * last modified: $Author: ctoutant $, $Date: 94/09/28 13:22:46 $ * * version: $Id: MTXINIT.C 1.91 94/09/28 13:22:46 ctoutant Exp $ * * * HwData * mtxCheckHwAll(void) * bool mtxSelectHw(HwData *pHardware) * HwModeData * mtxGetHwModes(void) * bool mtxSelectHwMode(HwModeData *pHwModeSelect) * bool mtxSetDisplayMode(HwModeData *pDisplayModeSelect, dword Zoom) * * dword mtxGetMgaSel(void) * void mtxGetInfo(HwModeData *pCurHwMode, HwModeData *pCurDispMode, * byte *InitBuffer, byte *VideoBuffer) * bool mtxSetLUT(word index, mtxRGB color) * void mtxClose(void) * ******************************************************************************/ #include "switches.h" #ifdef WINDOWS_NT #if defined(ALLOC_PRAGMA) #pragma alloc_text(PAGE,mtxCheckHwAll) #pragma alloc_text(PAGE,mtxSelectHw) #pragma alloc_text(PAGE,mtxGetHwModes) #pragma alloc_text(PAGE,mtxSelectHwMode) #pragma alloc_text(PAGE,mtxSetDisplayMode) #pragma alloc_text(PAGE,overScan) #pragma alloc_text(PAGE,mapPciVl) #pragma alloc_text(PAGE,MapBoard) #pragma alloc_text(PAGE,adjustDefaultVidset) #pragma alloc_text(PAGE,selectMgaInfoBoard) #pragma alloc_text(PAGE,UpdateHwModeTable) // #pragma alloc_text(PAGE,mtxGetMgaSel) #pragma alloc_text(PAGE,mtxGetInfo) #pragma alloc_text(PAGE,InitHwStruct) #pragma alloc_text(PAGE,mtxSetLUT) #pragma alloc_text(PAGE,mtxClose) #endif //Not to be paged out: // Hw // pMgaBaseAddr // iBoard // mtxVideoMode // pMgaDeviceExtension //#if defined(ALLOC_PRAGMA) //#pragma data_seg("PAGE") //#endif #else /* #ifdef WINDOWS_NT */ #include #include #include #include #include #endif /* #ifdef WINDOWS_NT */ #ifdef OS2 #include #pragma intrinsic(strcat, strcpy) #endif #ifdef WINDOWS #include "windows.h" #endif #include "bind.h" #include "defbind.h" #include "sxci.h" #include "def.h" #include "mga.h" #include "mgai_c.h" #include "mgai.h" #include "caddi.h" #include "mtxpci.h" #include "mtxvpro.h" #include "vidfile.h" #if ((!defined (WINDOWS_NT)) || (USE_DDC_CODE)) /*********** DDC CODE ****************/ #include "edid.h" /*********** DDC CODE ****************/ #endif /* Externals from mgainfo.c (which used to be mgainfo.h) */ /* #include "mgainfo.h" */ /* Default video parameters */ #ifdef WINDOWS_NT extern UCHAR DefaultVidset[]; extern word configSpace; #else extern char DefaultVidset[]; #endif /* Externals from tables.c (which used to be tables.h) */ /* #include "tables.h" */ extern OffScrData OffScrFBM_000_A[]; extern OffScrData iOffScrFBM_000_A[]; extern OffScrData OffScrFBM_010_A[]; extern OffScrData iOffScrFBM_010_A[]; extern OffScrData OffScrFBM_010_B[]; extern OffScrData iOffScrFBM_010_B[]; extern OffScrData OffScrFBM_011_A[]; extern OffScrData iOffScrFBM_011_A[]; extern OffScrData OffScrFBM_101_B[]; extern OffScrData iOffScrFBM_101_B[]; extern OffScrData OffScrFBM_111_A[]; extern OffScrData iOffScrFBM_111_A[]; extern OffScrData OffAth2[]; extern OffScrData iOffAth2[]; extern OffScrData OffAth4[]; extern OffScrData iOffAth4[]; extern HwModeData HwModesFBM_000_A[21]; extern HwModeInterlace iHwModesFBM_000_A[21]; extern HwModeData HwModesFBM_010_A[34]; extern HwModeInterlace iHwModesFBM_010_A[34]; extern HwModeData HwModesFBM_010_B[48]; extern HwModeInterlace iHwModesFBM_010_B[48]; extern HwModeData HwModesFBM_011_A[55]; extern HwModeInterlace iHwModesFBM_011_A[55]; extern HwModeData HwModesFBM_101_B[8]; extern HwModeInterlace iHwModesFBM_101_B[8]; extern HwModeData HwModesFBM_111_A[15]; extern HwModeInterlace iHwModesFBM_111_A[15]; extern HwModeData ModesAth2[63]; extern HwModeInterlace iModesAth2[63]; extern HwModeData ModesAth4[98]; extern HwModeInterlace iModesAth4[98]; #ifdef _WINDOWS_DLL16 /*** Definition for pool memory ***/ #define PAN_X 0 #define PAN_Y 1 #define PAN_DISP_WIDTH 2 #define PAN_DISP_HEIGHT 3 #define DB_SCALE 4 #define PAN_BOUND_LEFT 5 #define PAN_BOUND_TOP 6 #define PAN_BOUND_RIGHT 7 #define PAN_BOUND_BOTTOM 8 HINSTANCE hsxci=0; HINSTANCE huser=0; typedef long (FAR PASCAL *FARPROC2)(); static FARPROC2 fp1; word NbSxciLoaded=0; word FAR *pDllMem; #endif #ifdef PRINT_DEBUG extern int debug_printf( char *fmt, ... ); extern void openDebugfFile(char *s); extern void reOpenDebugfFile(); extern void closeDebugfFile(char *s); extern void imprimeBuffer(byte *InitBuf, byte *VideoBuf); #endif dword MgaSel; #ifdef WINDOWS_NT extern INTERFACE_TYPE NtInterfaceType; extern UCHAR MgaBusType[]; #define MGA_BUS_INVALID 0 #define MGA_BUS_PCI 1 #define MGA_BUS_ISA 2 ULONG PciSlot; PVOID pMgaDeviceExtension; PUCHAR pMgaBaseAddr; PUCHAR pciBiosRoutine; PUCHAR pMgaPciIo, pMgaPciConfigSpace; #define PCI_LEN 0x00000004 #define CONFIG_SPACE 0x0000c000 #define CONFIG_LEN 0x00000100 VIDEO_ACCESS_RANGE MgaPciCseAccessRange = {PCI_CSE, 0x00000000, PCI_LEN, 1, 0, 1}; VIDEO_ACCESS_RANGE MgaPciConfigAccessRange = {CONFIG_SPACE, 0x00000000, CONFIG_LEN, 1, 0, 1}; VIDEO_ACCESS_RANGE VideoProAccessRange = {0x00000240, 0x00000000, 0x20, 1, 1, 1}; typedef struct _MULTI_MODE { ULONG MulModeNumber; // unique mode Id ULONG MulWidth; // total width of mode ULONG MulHeight; // total height of mode ULONG MulPixWidth; // pixel depth of mode ULONG MulRefreshRate; // refresh rate of mode USHORT MulArrayWidth; // number of boards arrayed along X USHORT MulArrayHeight; // number of boards arrayed along Y UCHAR MulBoardNb[NB_BOARD_MAX]; // board numbers of required boards USHORT MulBoardMode[NB_BOARD_MAX]; // mode required from each board HwModeData *MulHwModes[NB_BOARD_MAX]; // pointers to required HwModeData } MULTI_MODE, *PMULTI_MODE; /*--------------------------------------------------------------------------*\ | HW_DEVICE_EXTENSION | | Define device extension structure. This is device dependant/private | information. | \*--------------------------------------------------------------------------*/ typedef struct _MGA_DEVICE_EXTENSION { ULONG SuperModeNumber; // Current mode number ULONG NumberOfSuperModes; // Total number of modes PMULTI_MODE pSuperModes; // Array of super-modes structures // For each board: ULONG NumberOfModes[NB_BOARD_MAX]; // Number of available modes ULONG NumberOfValidModes[NB_BOARD_MAX]; // Number of valid modes ULONG ModeFlags2D[NB_BOARD_MAX]; // 2D modes supported by each board ULONG ModeFlags3D[NB_BOARD_MAX]; // 3D modes supported by each board USHORT ModeFreqs[NB_BOARD_MAX][64]; // Refresh rates bit fields UCHAR ModeList[NB_BOARD_MAX][64]; // Valid hardware modes list HwModeData *pMgaHwModes[NB_BOARD_MAX]; // Array of mode information structs. BOOLEAN bUsingInt10; // May need this later PVOID KernelModeMappedBaseAddress[NB_BOARD_MAX]; // Kern-mode virt addr base of MGA regs PVOID UserModeMappedBaseAddress[NB_BOARD_MAX]; // User-mode virt addr base of MGA regs PVOID MappedAddress[]; // NUM_MGA_COMMON_ACCESS_RANGES elements } MGA_DEVICE_EXTENSION, *PMGA_DEVICE_EXTENSION; //#define ADDR_46E8_PORT (PVOID) ((ULONG)(((PMGA_DEVICE_EXTENSION)pMgaDeviceExtension)->MappedAddress[5]) + (0x46e8 - 0x46e8)) #define ADDR_46E8_PORT 0x46e8 #else /* #ifdef WINDOWS_NT */ volatile byte _Far *pMgaBaseAddr; #endif /* #ifdef WINDOWS_NT */ /* Global parameters */ byte iBoard=0; /* index of current selected board */ byte NbBoard=0; /* total board detected */ bool CheckHwAllDone=FALSE; bool SpecialModeOn = FALSE; /*VIDEOPRO*/ bool VAFCconnector; extern bool initVideoMode(word mode, byte pwidth); extern bool initVideoPro(byte mode, byte dactype); #ifdef OS2 word mtxVideoMode = mtxPASSTHRU; #else word mtxVideoMode; #endif long setTVP3026Freq ( volatile byte _Far *pDeviceParam, long fout, long reg, byte pWidth ); #ifndef __DDK_SRC__ extern dword BindingRC[NB_BOARD_MAX]; extern dword BindingCL[NB_BOARD_MAX]; #endif #if( !defined(_WINDOWS_DLL16) && !defined(INIT_ONLY)) #ifndef OS2 dword _Far *BufBind; SYSPARMS *sp; #ifndef __DDK_SRC__ byte* CaddiInit(byte *InitBuf, byte *VideoBuf); #else byte* InitDDK(byte *InitBuf, byte *VideoBuf); byte* ReInitDDK(byte *InitBuf, byte *VideoBuf); #endif void setTVP3026(volatile byte _Far *pDevice, long fout_voulue, long reg, word pWidth); #endif #endif HwData Hw[NB_BOARD_MAX+1]; dword presentMclk[NB_BOARD_MAX+1] = {0}; /* MCLK currently in use */ dword Dst0, Dst1; dword ProductMGA[NB_BOARD_MAX]; HwModeData *FirstMode[NB_BOARD_MAX]; byte InitBuf[NB_BOARD_MAX][INITBUF_S] = {0}; byte VideoBuf[NB_BOARD_MAX][VIDEOBUF_S] = {0}; extern dword crtcTab[NB_CRTC_PARAM]; extern vid vidtab[24]; char *mgainf = (char *)0; /*** PROTOTYPES ***/ bool MapBoard(void); static void overScan(void); void UpdateHwModeTable (char *,HwModeData *,HwModeInterlace *,bool); bool ProgrammeClock(byte Chip, dword Dst1, dword InfoDac); extern dword getmgasel(void); extern programme_reg_icd ( volatile byte _Far *pDevice, short reg, dword data ); #if 0 extern word detectVideoBoard(void); #endif void mtxMapVLBSpace(); bool mtxSetVLB(dword sel); bool mtxIsVLBBios (); void delay_us(dword delai); #ifndef WINDOWS_NT void setPciOptionReg(); #endif #ifdef WINDOWS_NT extern PUCHAR setmgasel(dword MgaSel, dword phyadr, dword limit); extern PVOID AllocateSystemMemory(ULONG NumberOfBytes); extern BOOLEAN bConflictDetected(ULONG ulAddressToVerify); extern PUCHAR pciBiosCallAddr(); #else /* #ifdef WINDOWS_NT */ #ifdef OS2 extern volatile byte _Far *setmgasel(dword MgaSel, dword phyadr, word limit); extern HWIsSelected(dword, dword , dword, dword, byte); #else extern volatile byte _Far *setmgasel(dword MgaSel, dword phyadr, dword limit); #endif #endif /* #ifdef WINDOWS_NT */ extern void GetMGAConfiguration(volatile byte _Far *pMgaBaseAddr, dword *Dst0, dword *Dst1, dword *InfoHardware); extern void MGASysInit(byte *); #ifdef OS2 extern char *selectMgaInfoBoard(); #else char *selectMgaInfoBoard(); #endif extern bool loadVidPar(dword Zoom, HwModeData *HwMode, HwModeData *DisplayMode); extern void calculCrtcParam(void); extern void MoveToVideoBuffer(byte *vidtab, byte *crtcTab, byte *VideoBuf); extern void MGAVidInit(byte *, byte *); dword mtxGetMgaSel(void); bool mtxLectureMgaInf(void); bool InitHwStruct(byte CurBoard, HwModeData *pHwModeData, word sizeArray, dword VramAvailable, dword DramAvailable); extern char *mtxConvertMgaInf( char * ); #ifdef _WINDOWS_DLL16 extern void FAR *memalloc(dword size); extern dword memfree(void FAR **mem); extern void AdjustDBWindow(void); #endif #ifdef WINDOWS dword ValMSec; int _Far pascal LibMain(HANDLE hInstance, WORD wDataSeg, WORD wHeapSize, LPSTR lpszCmdLine) { if (wHeapSize > 0) UnlockData(0); return 1; } #endif /*----------------------------------------------------- * mtxCheckHwAll * * This function returns the pointer to an array of MGA * hardware devices found in the system * * Return value: * >0 = Pointer to HwData structure * 0 = Error ; No MGA device found *-----------------------------------------------------*/ HwData * mtxCheckHwAll(void) { dword TmpDword; byte Board, TmpByte, DUB_SEL, ChipSet; dword PcbRev, TitanRev, DubRev; dword RamBanks; dword InfoHardware; void *pMgaInfo; bool dacSupportHires; #ifndef WINDOWS_NT byte i; // Modified for Windows NT: // Since we can't open files in the kernel-mode driver, MGA.INF // is read in the user-mode driver instead; so, prior to calling // _mtxCheckHwAll, mgainf already points to MGA.INF data and // all the MGA boards have been mapped already...so we don't have // to call MapBoard or mtxLectureMgaInf here. if (! CheckHwAllDone) { /*** Figure number of iteration in one tick (55 millisecond) ***/ #ifdef WINDOWS { dword _Far *tick = MAKELP(0x40, 0x6c); dword t; _asm{ pushf sti } /* enable the interrupt because of a hang bug */ ValMSec = 0; t = *tick + 1; while(t > *tick); t++; while(t > *tick) ValMSec++; _asm popf } #endif #ifdef PRINT_DEBUG openDebugfFile("\\SXCIEXT.LOG"); debug_printf(" ---- Premier appel CheckHwAll\n"); #endif if (! MapBoard()) { #ifdef PRINT_DEBUG debug_printf("MapBoard Fail\n"); #endif return(mtxFAIL); } } #ifdef PRINT_DEBUG else { reOpenDebugfFile(); debug_printf(" ---- appel (pas le premier) CheckHwAll\n"); } #endif if (! mtxLectureMgaInf()) { #ifdef PRINT_DEBUG closeDebugfFile("mtxLectureMgaInf Fail"); #endif return(mtxFAIL); } #endif /* #ifndef WINDOWS_NT */ /* Initialize Hw[] structure for each board */ for (Board=0; Board 1)) { // pHwMode has been initialized to NULL in MgaFindAdapter. // If it's not NULL here, it means we've been here before. // If we have more than one board, then InitHwStruct has allocated // memory for pHwMode, and we'll release it here. VideoPortReleaseBuffer(pMgaDeviceExtension, Hw[iBoard].pHwMode); Hw[iBoard].pHwMode = NULL; } #endif Hw[iBoard].pCurrentHwMode = NULL; Hw[iBoard].pCurrentDisplayMode = NULL; Hw[iBoard].CurrentZoomFactor = 0; Hw[iBoard].CurrentXStart = 0; Hw[iBoard].CurrentYStart = 0; mtxSetVideoMode(mtxADV_MODE); GetMGAConfiguration(pMgaBaseAddr, &Dst0, &Dst1, &InfoHardware); #ifdef PRINT_DEBUG { debug_printf("DST0 = 0x%08lx, DST1 = 0x%08lx InfoHardware = 0x%x\n", Dst0, Dst1, InfoHardware); } #endif /* Verify if DAC support resolution above 1280 */ dacSupportHires = !(Dst1 & TITAN_DST1_ABOVE1280_M); /* Test bit Above1280 */ Hw[Board].ProductType = (Dst0 & TITAN_DST0_PRODUCT_M) >> TITAN_DST0_PRODUCT_A; PcbRev = (Dst0 & TITAN_DST0_PCBREV_M) >> TITAN_DST0_PCBREV_A; mgaReadDWORD(*(pMgaBaseAddr+TITAN_OFFSET+TITAN_REV), TitanRev); TitanRev = (TitanRev & 0x000000ff) << 4; DubRev = 0 << 8; if( ((TitanRev >> 4) & 0x0000000f) < ATHENA_CHIP) PcbRev = 0xf - (PcbRev & 0xf); /* 4 bits for TITAN and ATLAS */ else PcbRev = 7 - (PcbRev & 0x7); /* 3 bits for ATHENA */ Hw[Board].ProductRev = PcbRev+TitanRev+DubRev; #if 0 /*** status presence of the VideoPro board ***/ if( detectVideoBoard() ) Hw[Board].ProductRev |= 0x1000; /* Set bit 12 to 1 */ else Hw[Board].ProductRev &= 0xffffefff; /* Set bit 12 to 0 */ #endif if( ((Hw[iBoard].ProductRev >> 4) & 0x0000000f) == ATHENA_CHIP) { /*------ Strap added for ATHENA ------------------------------*/ mgaReadDWORD(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_CONFIG), TmpDword); /** BEN we add this condition to fix bug shift left **/ /* For Impression Lite we force regular operation */ if ((Dst1 & TITAN_DST1_ABOVE1280_M) && (Dst1 & TITAN_DST1_200MHZ_M) && ((Hw[iBoard].ProductRev >> 4) & 0x0000000f) == ATHENA_CHIP ) { TmpDword = TmpDword & 0xfffffffb; /* bit 2=0: Board supports regular (135MHz/170MHz) operation */ } else { if((Dst1 & TITAN_DST1_200MHZ_M) >> TITAN_DST1_200MHZ_A) TmpDword = TmpDword & 0xfffffffb; /* bit 2=0: Board supports regular (135MHz/170MHz) operation */ else TmpDword = TmpDword | 0x00000004; /* bit 2=1: Board supports 200MHz operation */ } mgaWriteDWORD(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_CONFIG), TmpDword); if ( ( (InfoHardware == Info_Dac_ViewPoint) || (InfoHardware == Info_Dac_TVP3026) ) && (TmpDword & 0x00000004) ) /* support 200MHz */ dacSupportHires = 1; else dacSupportHires = 0; /*------ Strap added for ATHENA ------------------------------*/ /*** BEN I add this condition to prevent to program NOMUX for board MGA-PCI/2+ and MGA-VLB/2+ because the bit NOMUX is used to set the clock ***/ if ( (InfoHardware == Info_Dac_BT485) || (InfoHardware == Info_Dac_ATT2050) || (InfoHardware == Info_Dac_PX2085) ) { /*------ Strap added for ATHENA --------------------------*/ mgaReadDWORD(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_CONFIG), TmpDword); if((Dst1 & TITAN_DST1_NOMUXES_M) >> TITAN_DST1_NOMUXES_A) TmpDword = TmpDword & 0xffffffdf; /* bit 5=0: */ else TmpDword = TmpDword | 0x00000020; /* bit 5=1: */ mgaWriteDWORD(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_CONFIG), TmpDword); /*------ Strap added for ATHENA --------------------------*/ } } /*** BEN open issue */ Hw[Board].ShellRev = 0; Hw[Board].BindingRev = BINDING_REV; /*** ----- DUBIC PATCH Disable mouse IRQ and proceed ------ ***/ mgaWriteBYTE(*(pMgaBaseAddr + DUBIC_OFFSET + DUBIC_NDX_PTR), 0x08); mgaReadBYTE(*(pMgaBaseAddr + DUBIC_OFFSET + DUBIC_DUB_SEL), DUB_SEL); mgaWriteBYTE(*(pMgaBaseAddr + DUBIC_OFFSET + DUBIC_DUB_SEL), 0x00); /*** ------------------------------------------------------ ***/ mgaWriteBYTE(*(pMgaBaseAddr+DUBIC_OFFSET + DUBIC_NDX_PTR), DUBIC_DUB_CTL2); mgaReadBYTE(*(pMgaBaseAddr+DUBIC_OFFSET + DUBIC_DATA), TmpByte); /*** ----- DUBIC PATCH ReEnable mouse IRQ ----------------- ***/ mgaWriteBYTE(*(pMgaBaseAddr + DUBIC_OFFSET + DUBIC_NDX_PTR), 0x08); mgaWriteBYTE(*(pMgaBaseAddr + DUBIC_OFFSET + DUBIC_DUB_SEL), DUB_SEL); /*** ------------------------------------------------------ ***/ Hw[Board].Sync = TmpByte & 0x1; #if 0 mgaReadDWORD(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_OPMODE), TmpDword); if (TmpDword & 0x00000100) Hw[Board].PortCfg = 1; /* Mouse enable */ else if (TmpByte & 0x04) Hw[Board].PortCfg = 2; /* Laser enable */ else Hw[Board].PortCfg = 0; /* Port disable */ #endif /* Interrupt number for the mouse or the laser port */ mgaReadBYTE(*(pMgaBaseAddr+DUBIC_OFFSET + DUBIC_DUB_SEL), TmpByte); TmpByte = (TmpByte & 0x18) >> 3; switch (TmpByte) { case 0: Hw[Board].PortIRQ = (byte)-1; break; case 1: Hw[Board].PortIRQ = 3; break; case 2: Hw[Board].PortIRQ = 4; break; case 3: Hw[Board].PortIRQ = 5; break; } mgaReadDWORD(*(pMgaBaseAddr+TITAN_OFFSET+TITAN_OPMODE),TmpDword); if (TmpDword & TITAN_MOUSEMAP_M) Hw[Board].MouseMap = 0x238; else Hw[Board].MouseMap = 0x23c; mgaReadBYTE(*(pMgaBaseAddr+DUBIC_OFFSET + DUBIC_DUB_SEL), TmpByte); TmpByte = (TmpByte & 0x70) >> 5; switch (TmpByte) { case 0: Hw[Board].MouseIRate = 0; break; case 1: Hw[Board].MouseIRate = 25; break; case 2: Hw[Board].MouseIRate = 50; break; case 3: Hw[Board].MouseIRate = 100; break; case 4: Hw[Board].MouseIRate = 200; break; } /*Hw[Board].DacType = InfoHardware & 0x00000003; */ /*** BEN Temporary translate code ***/ #if 0 /*VIDEOPRO*/ VAFCconnector = 0; #endif switch(InfoHardware) { case Info_Dac_BT481: case Info_Dac_BT482: Hw[Board].DacType = BT482; break; case Info_Dac_Sierra: Hw[Board].DacType = SIERRA; break; case Info_Dac_ViewPoint: Hw[Board].DacType = VIEWPOINT; break; case Info_Dac_TVP3026: Hw[Board].DacType = TVP3026; break; case Info_Dac_BT484: Hw[Board].DacType = BT484; break; case Info_Dac_BT485: case Info_Dac_ATT2050: Hw[Board].DacType = BT485; break; case Info_Dac_Chameleon: Hw[Board].DacType = CHAMELEON; break; case Info_Dac_PX2085: #if 0 /*VIDEOPRO*/ VAFCconnector = 1; #endif #ifndef WINDOWS_NT Hw[Board].DacType = BT485; #else Hw[Board].DacType = PX2085; #endif /* #ifndef WINDOWS_NT */ break; default: return(mtxFAIL); } #ifdef PRINT_DEBUG { debug_printf("Dactype[%d] = %x\n", Board, Hw[Board].DacType); } #endif /*** Cursor info init ***/ switch(Hw[Board].DacType) { case BT482: Hw[Board].cursorInfo.MaxWidth = 32; Hw[Board].cursorInfo.MaxHeight = 32; Hw[Board].cursorInfo.MaxDepth = 2; Hw[Board].cursorInfo.MaxColors = 2; break; case BT485: case PX2085: case VIEWPOINT: Hw[Board].cursorInfo.MaxWidth = 64; Hw[Board].cursorInfo.MaxHeight = 64; Hw[Board].cursorInfo.MaxDepth = 2; Hw[Board].cursorInfo.MaxColors = 2; break; case TVP3026: Hw[Board].cursorInfo.MaxWidth = 64; Hw[Board].cursorInfo.MaxHeight = 64; Hw[Board].cursorInfo.MaxDepth = 2; Hw[Board].cursorInfo.MaxColors = 3; break; default: Hw[Board].cursorInfo.MaxWidth = 0; Hw[Board].cursorInfo.MaxHeight = 0; Hw[Board].cursorInfo.MaxDepth = 0; Hw[Board].cursorInfo.MaxColors = 0; break; } Hw[Board].cursorInfo.CurWidth = 0; Hw[Board].cursorInfo.CurHeight = 0; Hw[Board].cursorInfo.HotSX = 0; Hw[Board].cursorInfo.HotSY = 0; /* Form Rambank value */ RamBanks = ((Dst1 & TITAN_DST1_RAMBANK_M) << 8L) | ((Dst0 & 0xfe000000) >> 24L) | ((Dst1 & TITAN_DST1_RAMBANK0_M) >> TITAN_DST1_RAMBANK0_A); /*** Check the ZTAG bit ***/ if (RamBanks & (dword)0x40) *((byte*) (InitBuf[Board] + INITBUF_ZTagFlag)) = TRUE; else *((byte*) (InitBuf[Board] + INITBUF_ZTagFlag)) = FALSE; RamBanks = RamBanks & 0x1bf; /* Mask le ZTAG et bits dont care */ #ifdef PRINT_DEBUG { debug_printf("RamBank = %x\n", RamBanks); } #endif switch((Hw[iBoard].ProductRev >> 4) & 0x0000000f) { case TITAN_CHIP: ChipSet = TITAN_CHIP; break; case ATLAS_CHIP: ChipSet = ATLAS_CHIP; /* Check if VLB2 board */ mgaReadDWORD(*(pMgaBaseAddr+0x2000),TmpDword); if (TmpDword == (dword)0x0518102b) /* ID Matrox */ mgaWriteBYTE(*(pMgaBaseAddr+0x2040),0x01); /* Program option reg */ #ifndef WINDOWS_NT else /* PCI bus */ /* If PCI disable PCI posted write feature if system use Ares chipset */ disPostedWFeature(); break; #endif /* #ifndef WINDOWS_NT */ case ATHENA_CHIP: ChipSet = ATHENA_CHIP; /*** BEN se programme maintenant par le clock synthetiser ***/ /* Check if VLB2 board */ mgaReadDWORD(*(pMgaBaseAddr+0x2000),TmpDword); if (TmpDword == (dword)0x0518102b) /* ID Matrox */ mgaWriteBYTE(*(pMgaBaseAddr+0x2040),0x01); /* Program option reg */ break; } /*** Define ProductMGA ***/ if (RamBanks == (dword)0x001 && ChipSet == TITAN_CHIP) ProductMGA[Board] = MGA_ULT_1M; else if (RamBanks == (dword)0x004 && ChipSet == TITAN_CHIP) ProductMGA[Board] = MGA_ULT_2M; else if (RamBanks == (dword)0x005 && ChipSet == TITAN_CHIP) ProductMGA[Board] = MGA_IMP_3M; else if (RamBanks == (dword)0x025 && ChipSet == TITAN_CHIP) ProductMGA[Board] = MGA_IMP_3M_Z; else if (RamBanks == (dword)0x09C && ChipSet == TITAN_CHIP) ProductMGA[Board] = MGA_PRO_4M5; else if (RamBanks == (dword)0x13C && ChipSet == TITAN_CHIP) ProductMGA[Board] = MGA_PRO_4M5_Z; else if (RamBanks == (dword)0x004 && (ChipSet == ATLAS_CHIP || ChipSet == ATHENA_CHIP)) ProductMGA[Board] = MGA_PCI_2M; else if (RamBanks == (dword)0x005 && (ChipSet == ATLAS_CHIP || ChipSet == ATHENA_CHIP)) ProductMGA[Board] = MGA_PCI_4M; else { #ifdef PRINT_DEBUG closeDebugfFile("RamBanks Inconnue"); #endif return(mtxFAIL); } /*** Define Product type for external use ***/ if( ChipSet == TITAN_CHIP ) { if( ProductMGA[Board]==MGA_ULT_1M || ProductMGA[Board]==MGA_ULT_2M ) Hw[Board].ProductType |= (dword)MGA_ULTIMA<<16; else if( ProductMGA[Board]==MGA_PRO_4M5 || ProductMGA[Board]==MGA_PRO_4M5_Z ) Hw[Board].ProductType |= (dword)MGA_IMPRESSION_PRO<<16; else Hw[Board].ProductType |= (dword)MGA_IMPRESSION<<16; } else if( ChipSet == ATLAS_CHIP ) { if( InfoHardware == Info_Dac_PX2085 ) Hw[Board].ProductType |= (dword)MGA_ULTIMA_VAFC<<16; else if( (Dst1 & TITAN_DST1_200MHZ_M) && !(Dst1 & TITAN_DST1_ABOVE1280_M)) Hw[Board].ProductType |= (dword)MGA_ULTIMA_PLUS_200<<16; else if( InfoHardware == Info_Dac_ViewPoint ) Hw[Board].ProductType |= (dword)MGA_ULTIMA_PLUS<<16; else Hw[Board].ProductType |= (dword)MGA_ULTIMA<<16; } else /* Athena */ { if ((Dst1 & TITAN_DST1_ABOVE1280_M) && (Dst1 & TITAN_DST1_200MHZ_M)) Hw[Board].ProductType |= (dword)MGA_IMPRESSION_LTE<<16; else if( InfoHardware == Info_Dac_TVP3026) Hw[Board].ProductType |= (dword)MGA_IMPRESSION_PLUS<<16; else if( InfoHardware == Info_Dac_ViewPoint ) Hw[Board].ProductType |= (dword)MGA_ULTIMA_PLUS<<16; else Hw[Board].ProductType |= (dword)MGA_ULTIMA<<16; } #ifdef PRINT_DEBUG { debug_printf("ProductMGA[%d] = %x\n", Board, ProductMGA[Board]); } #endif if(! ProgrammeClock(ChipSet, Dst1, InfoHardware)) return(mtxFAIL); switch (ProductMGA[Board]) { case MGA_ULT_1M: if(!(InitHwStruct(Board, HwModesFBM_000_A, sizeof(HwModesFBM_000_A), 1048576, 0))) { #ifdef PRINT_DEBUG closeDebugfFile("MGA_ULT_1M : InitHwStruct Fail"); #endif return(mtxFAIL); } UpdateHwModeTable (pMgaInfo, FirstMode[Board], iHwModesFBM_000_A, dacSupportHires); break; case MGA_ULT_2M: if(!(InitHwStruct(Board, HwModesFBM_010_A, sizeof(HwModesFBM_010_A), 2097152, 0))) { #ifdef PRINT_DEBUG closeDebugfFile("MGA_ULT_2M : InitHwStruct Fail"); #endif return(mtxFAIL); } UpdateHwModeTable (pMgaInfo, FirstMode[Board], iHwModesFBM_010_A, dacSupportHires); break; case MGA_IMP_3M: if(!(InitHwStruct(Board, HwModesFBM_010_B, sizeof(HwModesFBM_010_B), 3145728, 0))) { #ifdef PRINT_DEBUG closeDebugfFile("MGA_IMP_3M : InitHwStruct Fail"); #endif return(mtxFAIL); } UpdateHwModeTable (pMgaInfo, FirstMode[Board], iHwModesFBM_010_B, dacSupportHires); break; case MGA_IMP_3M_Z: if(!(InitHwStruct(Board, HwModesFBM_011_A, sizeof(HwModesFBM_011_A), 3145728, 2097152))) { #ifdef PRINT_DEBUG closeDebugfFile("MGA_IMP_3M_Z : InitHwStruct Fail"); #endif return(mtxFAIL); } UpdateHwModeTable (pMgaInfo, FirstMode[Board], iHwModesFBM_011_A, dacSupportHires); break; case MGA_PRO_4M5: if(!(InitHwStruct(Board, HwModesFBM_101_B, sizeof(HwModesFBM_101_B), 4718592, 0))) { #ifdef PRINT_DEBUG closeDebugfFile("MGA_PRO_4M5 : InitHwStruct Fail"); #endif return(mtxFAIL); } UpdateHwModeTable (pMgaInfo, FirstMode[Board], iHwModesFBM_101_B, dacSupportHires); break; case MGA_PRO_4M5_Z: if(!(InitHwStruct(Board, HwModesFBM_111_A, sizeof(HwModesFBM_111_A), 4718592, 4194304))) { #ifdef PRINT_DEBUG closeDebugfFile("MGA_PRO_4M5_Z : InitHwStruct Fail"); #endif return(mtxFAIL); } UpdateHwModeTable (pMgaInfo, FirstMode[Board], iHwModesFBM_111_A, dacSupportHires); break; case MGA_PCI_2M: if(!(InitHwStruct(Board, ModesAth2, sizeof(ModesAth2), 2097152, 0))) return(mtxFAIL); UpdateHwModeTable (pMgaInfo, FirstMode[Board], iModesAth2, dacSupportHires); break; case MGA_PCI_4M: if(!(InitHwStruct(Board, ModesAth4, sizeof(ModesAth4), 4194304, 0))) return(mtxFAIL); UpdateHwModeTable (pMgaInfo, FirstMode[Board], iModesAth4, dacSupportHires); break; default: { #ifdef PRINT_DEBUG closeDebugfFile("Produit Inconnue"); #endif return(mtxFAIL); } } if (Hw[Board].VGAEnable == 1) mtxSetVideoMode(mtxVGA); #ifdef WINDOWS_NT // Do not free this now, since we do not use setmgasel in mtxSelectHw. // VideoPortFreeDeviceBase(pMgaDeviceExtension, pMgaBaseAddr); #endif } /*** for loop Board... ***/ /* Set the OPTION register for ATLAS PCI */ #ifndef WINDOWS_NT setPciOptionReg(); #endif /* Indicates end of array */ Hw[Board].MapAddress = (dword)-1; /* Default initialisation */ Hw[iBoard].pCurrentDisplayMode = Hw[iBoard].pCurrentHwMode; #if( !defined( _WINDOWS_DLL16) && !defined(OS2) && !defined(INIT_ONLY)) #ifndef WINDOWS_NT if (! CheckHwAllDone) { /* Allocate a static buffer for the command (C-Binding -> CADDI) */ #ifndef __DDK_SRC__ BufBind = mtxAllocBuffer(BUF_BIND_SIZE); #endif /* Allocate a static RC and a clip list for each MGA device */ for (i=0; Hw[i].MapAddress != (dword)-1 ; i++) { if (! mtxSelectHw(&Hw[i])) { #ifdef PRINT_DEBUG closeDebugfFile("mtxSelectHw(&Hw[]) == 0\n"); #endif return(mtxFAIL); } #ifndef __DDK_SRC__ BindingRC[i] = (dword)NULL; /*** *** _tDDK_STATE needs to be NULL'ed here if you want the DDK *** to behave exactly like the SDK ***/ #endif if (!mtxSelectHwMode(Hw[iBoard].pCurrentHwMode)) { #ifdef PRINT_DEBUG closeDebugfFile("mtxSelectHwMode(Hw[].pCurrentHwMode == 0"); #endif return(mtxFAIL); } #ifndef __DDK_SRC__ BindingRC[i] = (dword)mtxAllocRC(NULL); BindingCL[i] = (dword)mtxAllocCL(1); #endif mtxSetVideoMode(mtxVGA); } } #endif /* #ifndef WINDOWS_NT */ #endif /* #if( !defined( _WINDOWS_DLL16) && !defined(OS2))... */ CheckHwAllDone = TRUE; #ifdef PRINT_DEBUG closeDebugfFile("Sortie Ok CheckHwAll"); #endif return(&Hw[0]); } /*------------------------------------------------ * mtxSelectHw * * Select the MGA device to be used for subsequent * drawing operations * * Return: * mtxOK : Hardware select successful * mtxFAIL : Hardware select failure *------------------------------------------------*/ bool mtxSelectHw(HwData *pHardware) { HwData *pScanHwData; bool FlagFoundHwData; /*** VALIDATE pHardware and set iBoard ***/ FlagFoundHwData = FALSE; iBoard = 0; for (pScanHwData = &Hw[0]; pScanHwData->MapAddress != (dword)-1; pScanHwData++, iBoard++) { if (pScanHwData == pHardware) { FlagFoundHwData = TRUE; break; } } if (! FlagFoundHwData) return(mtxFAIL); #ifdef WINDOWS_NT pMgaBaseAddr = Hw[iBoard].BaseAddress; #else pMgaBaseAddr = setmgasel(MgaSel, Hw[iBoard].MapAddress, 4); #endif #ifdef OS2 HWIsSelected(ProductMGA[iBoard], Hw[iBoard].ProductType, Hw[iBoard].ProductRev, Hw[iBoard].MapAddress, Hw[iBoard].DacType); #endif #if( !defined(WINDOWS) && !defined(OS2) && !defined(WINDOWS_NT) && !defined(INIT_ONLY)) #ifndef __DDK_SRC__ CaddiReInit(InitBuf[iBoard], VideoBuf[iBoard]); #else ReInitDDK(InitBuf[iBoard], VideoBuf[iBoard]); #endif #endif return(mtxOK); } /*------------------------------------------------------ * mtxGetHwModes * * This function returns a pointer to a list of hardware * modes available for the current MGA device * as selected by mtxSelectHw() * * Return: * HwModes = 0 : MGA device not found * HwModes != 0 : Pointer to HwModes array *------------------------------------------------------*/ HwModeData *mtxGetHwModes(void) { if (NbBoard == 0) return(0); return(FirstMode[iBoard]); } /*------------------------------------------------------ * mtxGetRefreshRates * * This function returns a word that contains a bit field * of possible frequency for a specific resolution and * pixel depth. * * Return: *------------------------------------------------------*/ word mtxGetRefreshRates(HwModeData *pHwModeSelect) { word FreqRes,i; for (FreqRes = 0,i = 0; ResParam[i].DispWidth != (word) -1; i++) { if ((ResParam[i].DispWidth == pHwModeSelect->DispWidth) && (ResParam[i].PixDepth == pHwModeSelect->PixWidth)) { switch (ResParam[i].RefreshRate) { // 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 case 43: FreqRes |= 0x0001; break; case 56: FreqRes |= 0x0002; break; case 60: FreqRes |= 0x0004; break; case 66: FreqRes |= 0x0008; break; case 70: FreqRes |= 0x0010; break; case 72: FreqRes |= 0x0020; break; case 75: FreqRes |= 0x0040; break; case 76: FreqRes |= 0x0080; break; case 80: FreqRes |= 0x0100; break; case 85: FreqRes |= 0x0200; break; case 90: FreqRes |= 0x0400; break; case 100: FreqRes |= 0x0800; break; case 120: FreqRes |= 0x1000; break; } } } return(FreqRes); } /*---------------------------------------------------------- * mtxSelectHwMode * * Select from the list of available hardware modes returned * by mtxGetHwModes() * * Return: * mtxOK : HwMode select successfull * mtxFAIL : HwMode select failure * *----------------------------------------------------------*/ bool mtxSelectHwMode(HwModeData *pHwModeSelect) { bool FlagFindMode; byte TmpByte; HwModeData *pScanHwMode; general_info *generalInfo; dword DST0, DST1, Info; generalInfo = (general_info *)selectMgaInfoBoard(); FlagFindMode = FALSE; for ( pScanHwMode = FirstMode[iBoard]; pScanHwMode->DispWidth != (word)-1; pScanHwMode++) { if (pScanHwMode == pHwModeSelect) { FlagFindMode = TRUE; break; } } if (NbBoard == 0 || FlagFindMode == FALSE) return(mtxFAIL); Hw[iBoard].pCurrentHwMode = NULL; Hw[iBoard].pCurrentDisplayMode = NULL; mtxSetVideoMode(mtxADV_MODE); Hw[iBoard].pCurrentHwMode = pHwModeSelect; if(pHwModeSelect->DispType & 0x04) /* LUT mode */ { *((byte*) (InitBuf[iBoard] + INITBUF_LUTMode)) = TRUE; } else { *((byte*) (InitBuf[iBoard] + INITBUF_LUTMode)) = FALSE; } /* Initialize a init buffer for CADDI */ if (pHwModeSelect->PixWidth == 24) /* PACK PIXEL */ *((byte*) (InitBuf[iBoard] + INITBUF_PWidth)) = 0x12; else *((byte*) (InitBuf[iBoard] + INITBUF_PWidth)) = pHwModeSelect->PixWidth >> 4; *((word*) (InitBuf[iBoard] + INITBUF_ScreenWidth)) = pHwModeSelect->FbPitch; *((word*) (InitBuf[iBoard] + INITBUF_ScreenHeight)) = pHwModeSelect->DispHeight; #ifdef WINDOWS_NT *((UINT_PTR*)(InitBuf[iBoard] + INITBUF_MgaOffset)) = (UINT_PTR)pMgaBaseAddr; #else #ifdef __WATCOMC__ #ifdef __WATCOM_PHAR__ /* Watcom & Phar Lap */ *((dword*)(InitBuf[iBoard] + INITBUF_MgaOffset)) = 0; #else /* Watcom & Rational */ *((dword*)(InitBuf[iBoard] + INITBUF_MgaOffset)) = (dword)pMgaBaseAddr;; #endif #elif __MICROSOFTC600__ *((dword*)(InitBuf[iBoard] + INITBUF_MgaOffset)) = (dword)pMgaBaseAddr;; #else /* High C & Phar Lap */ *((dword*)(InitBuf[iBoard] + INITBUF_MgaOffset)) = 0; #endif *((word*) (InitBuf[iBoard] + INITBUF_MgaSegment)) = MgaSel >> 16; #endif /* #ifdef WINDOWS_NT */ /* Default setting */ *((byte*) (InitBuf[iBoard] + INITBUF_ZBufferFlag)) = FALSE; *((byte*) (InitBuf[iBoard] + INITBUF_ZinDRAMFlag)) = FALSE; *((dword*)(InitBuf[iBoard] + INITBUF_ZBufferHwAddr)) = 0; switch(generalInfo->BitOperation8_16) { case BIT8: *((byte*)(InitBuf[iBoard] + INITBUF_16)) = 2; break; case BIT16: *((byte*)(InitBuf[iBoard] + INITBUF_16)) = 1; break; case BITNARROW16: *((byte*)(InitBuf[iBoard] + INITBUF_16)) = 3; break; default: *((byte*)(InitBuf[iBoard] + INITBUF_16)) = 0; break; } /* If on top of VGA, we must program in 16bit narrow absolutely */ if ((Hw[iBoard].ProductType & BOARD_MGA_VL_M) == BOARD_MGA_VL) { *((byte*)(InitBuf[iBoard] + INITBUF_16)) = 2; /* 8-bit mode */ } else { if (Hw[iBoard].MapAddress == MGA_ISA_BASE_1) *((byte*)(InitBuf[iBoard] + INITBUF_16)) = 1; } /* Transfer DMA informations from mga.inf */ *((byte*) (InitBuf[iBoard] + INITBUF_DMAEnable)) = (byte)generalInfo->DmaEnable; *((byte*) (InitBuf[iBoard] + INITBUF_DMAChannel)) = (byte)generalInfo->DmaChannel; *((byte*) (InitBuf[iBoard] + INITBUF_DMAType)) = (byte)generalInfo->DmaType; *((byte*) (InitBuf[iBoard] + INITBUF_DMAXferWidth)) = (byte)generalInfo->DmaXferWidth; /* Special case for MGA_IMP_3M_Z at 1024x768x32: we act like an MGA_IMP_3M */ if (ProductMGA[iBoard] == MGA_IMP_3M_Z && pHwModeSelect->DispWidth == 1024 && pHwModeSelect->PixWidth == 32) { ProductMGA[iBoard] = MGA_IMP_3M; SpecialModeOn = TRUE; } /* Reset to the real value of FBM when the flag is on and this is not the special mode */ if (SpecialModeOn == TRUE && (pHwModeSelect->DispWidth != 1024 || pHwModeSelect->PixWidth != 32)) { ProductMGA[iBoard] = MGA_IMP_3M_Z; SpecialModeOn = FALSE; } switch (ProductMGA[iBoard]) { case MGA_ULT_1M: *((byte*) (InitBuf[iBoard] + INITBUF_FBM)) = 0; break; case MGA_ULT_2M: case MGA_IMP_3M: case MGA_PCI_4M: *((byte*) (InitBuf[iBoard] + INITBUF_FBM)) = 2; break; case MGA_IMP_3M_Z: *((byte*) (InitBuf[iBoard] + INITBUF_FBM)) = 3; break; case MGA_PRO_4M5: *((byte*) (InitBuf[iBoard] + INITBUF_FBM)) = 5; break; case MGA_PRO_4M5_Z: *((byte*) (InitBuf[iBoard] + INITBUF_FBM)) = 7; break; case MGA_PCI_2M: if (pHwModeSelect->ZBuffer) *((byte*) (InitBuf[iBoard] + INITBUF_FBM)) = 10; else *((byte*) (InitBuf[iBoard] + INITBUF_FBM)) = 2; break; default: return(mtxFAIL); } if (pHwModeSelect->ZBuffer) { switch (ProductMGA[iBoard]) { case MGA_IMP_3M: /* We can do Z-buffer in VRAM */ *((byte*) (InitBuf[iBoard] + INITBUF_ZBufferFlag)) = TRUE; *((byte*) (InitBuf[iBoard] + INITBUF_ZinDRAMFlag)) = FALSE; *((dword*)(InitBuf[iBoard] + INITBUF_ZBufferHwAddr)) = 0x200000; break; case MGA_IMP_3M_Z: *((byte*) (InitBuf[iBoard] + INITBUF_ZBufferFlag)) = TRUE; *((byte*) (InitBuf[iBoard] + INITBUF_ZinDRAMFlag)) = TRUE; *((dword*)(InitBuf[iBoard] + INITBUF_ZBufferHwAddr)) = 0x400000; break; case MGA_PRO_4M5_Z: *((byte*) (InitBuf[iBoard] + INITBUF_ZBufferFlag)) = TRUE; *((byte*) (InitBuf[iBoard] + INITBUF_ZinDRAMFlag)) = TRUE; *((dword*)(InitBuf[iBoard] + INITBUF_ZBufferHwAddr)) = 0x600000; break; case MGA_PCI_4M: *((byte*) (InitBuf[iBoard] + INITBUF_ZBufferFlag)) = TRUE; *((byte*) (InitBuf[iBoard] + INITBUF_ZinDRAMFlag)) = FALSE; *((dword*)(InitBuf[iBoard] + INITBUF_ZBufferHwAddr)) = 0x200000; break; case MGA_PCI_2M: *((byte*) (InitBuf[iBoard] + INITBUF_ZBufferFlag)) = TRUE; *((byte*) (InitBuf[iBoard] + INITBUF_ZinDRAMFlag)) = FALSE; *((dword*)(InitBuf[iBoard] + INITBUF_ZBufferHwAddr)) = 0x100000; break; } } /* This blank is used before setting TITAN_FBM bit */ /* (done in GetMGAConfiguration and MGASysInit) */ /* Blank the screen */ mgaWriteBYTE(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_SEQ_ADDR), 0x01); mgaReadBYTE(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_SEQ_DATA), TmpByte); TmpByte |= 0x20; /* screen off */ mgaWriteBYTE(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_SEQ_DATA), TmpByte); GetMGAConfiguration(pMgaBaseAddr, &DST0, &DST1, &Info); *((dword*) (InitBuf[iBoard] + INITBUF_DST0)) = DST0; *((dword*) (InitBuf[iBoard] + INITBUF_DST1)) = DST1; *((dword*) (InitBuf[iBoard] + INITBUF_DACType)) = Info; /** Default setting **/ *((byte*) (InitBuf[iBoard] + INITBUF_DB_SideSide)) = FALSE; *((byte*) (InitBuf[iBoard] + INITBUF_DB_FrontBack)) = FALSE; /*** CALCULATION OF YDSTORG FOR MGA_PCI_4M ***/ if (ProductMGA[iBoard] == MGA_PCI_4M) { { dword NbBytes, PixelTransit, lines, offset; dword Width, Height, PixelWidth, FbPitch; if (pHwModeSelect->PixWidth == 24) /* PACK PIXEL */ { Width = (dword)((pHwModeSelect->DispWidth * 3) >> 2); FbPitch = (dword)(pHwModeSelect->FbPitch * 3) >> 2; PixelWidth = 4; } else { Width = (dword)pHwModeSelect->DispWidth; PixelWidth = (dword)((pHwModeSelect->PixWidth)/8); FbPitch = (dword)pHwModeSelect->FbPitch; } Height = (dword)pHwModeSelect->DispHeight; NbBytes = Width * Height * PixelWidth; if (NbBytes > (dword)2097152) { PixelTransit = (dword)2097152 / PixelWidth; lines = (dword)(PixelTransit / FbPitch); offset = (PixelTransit - (FbPitch * lines)) * PixelWidth; if (pHwModeSelect->PixWidth == 24) /* PACK PIXEL */ *((dword*) (InitBuf[iBoard] + INITBUF_YDSTORG)) = offset; else *((dword*) (InitBuf[iBoard] + INITBUF_YDSTORG)) = offset / PixelWidth; } else { *((dword*) (InitBuf[iBoard] + INITBUF_YDSTORG)) = 0; } } } else { *((dword*) (InitBuf[iBoard] + INITBUF_YDSTORG)) = 0; } /*--------------------------------------------------------------*/ /** If Double Buffering mode (software) **/ if((pHwModeSelect->DispType & 0x10) && /* DB mode */ !(pHwModeSelect->DispType & 0x04) ) /* not LUT mode */ { /* Check for exception case: DB mode 16 bit with Z for PCI/2M */ if( (ProductMGA[iBoard]==MGA_PCI_2M) && pHwModeSelect->ZBuffer && pHwModeSelect->PixWidth == 8 && Hw[iBoard].DacType == TVP3026) { *((dword*) (InitBuf[iBoard] + INITBUF_DB_YDSTORG)) = *((dword*) (InitBuf[iBoard] + INITBUF_YDSTORG)); *((byte*) (InitBuf[iBoard] + INITBUF_DB_FrontBack)) = TRUE; /** Caddi has to work in 16-bit **/ *((byte*) (InitBuf[iBoard] + INITBUF_PWidth)) = 16 >> 4; } else { if(ProductMGA[iBoard]==MGA_PCI_2M) { *((dword*) (InitBuf[iBoard] + INITBUF_DB_YDSTORG)) = (dword)((dword)pHwModeSelect->DispWidth * (dword)pHwModeSelect->DispHeight); } else { if (pHwModeSelect->ZBuffer && pHwModeSelect->PixWidth==8) { /*** Must start on a boundary of 1M (for Z buffer alignment) ***/ *((dword*) (InitBuf[iBoard] + INITBUF_DB_YDSTORG)) = 0x100000 / (pHwModeSelect->PixWidth / 8); } else { *((dword*) (InitBuf[iBoard] + INITBUF_DB_YDSTORG)) = (dword)((dword)pHwModeSelect->DispWidth * (dword)pHwModeSelect->DispHeight); } } *((byte*) (InitBuf[iBoard] + INITBUF_DB_SideSide)) = TRUE; } } else { *((dword*) (InitBuf[iBoard] + INITBUF_DB_YDSTORG)) = *((dword*) (InitBuf[iBoard] + INITBUF_YDSTORG)); } /*--------------------------------------------------------------*/ /* To communicate the information to WINDOWS */ Hw[iBoard].YDstOrg = *((dword*) (InitBuf[iBoard] + INITBUF_YDSTORG)); /*** Program YDSTORG ***/ mgaWriteDWORD(*(pMgaBaseAddr + TITAN_OFFSET + TITAN_YDSTORG), Hw[iBoard].YDstOrg ); switch((Hw[iBoard].ProductRev >> 4) & 0x0000000f) { case TITAN_CHIP: *((byte*) (InitBuf[iBoard] + INITBUF_ChipSet)) = TITAN_CHIP; *((byte*) (InitBuf[iBoard] + INITBUF_DubicPresent)) = 1; break; case ATLAS_CHIP: *((byte*) (InitBuf[iBoard] + INITBUF_ChipSet)) = ATLAS_CHIP; mgaReadBYTE(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_CONFIG), TmpByte); mgaWriteBYTE(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_CONFIG), TmpByte | TITAN_NODUBIC_M); *((byte*) (InitBuf[iBoard] + INITBUF_DubicPresent)) = 0; break; case ATHENA_CHIP: default: *((byte*) (InitBuf[iBoard] + INITBUF_ChipSet)) = ATHENA_CHIP; mgaReadBYTE(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_CONFIG), TmpByte); mgaWriteBYTE(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_CONFIG), TmpByte | TITAN_NODUBIC_M); *((byte*) (InitBuf[iBoard] + INITBUF_DubicPresent)) = 0; break; } MGASysInit(InitBuf[iBoard]); /* Unblank the screen */ mgaWriteBYTE(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_SEQ_ADDR), 0x01); mgaReadBYTE(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_SEQ_DATA), TmpByte); TmpByte &= 0xdf; /* screen on */ mgaWriteBYTE(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_SEQ_DATA), TmpByte); #if( !defined(_WINDOWS_DLL16) && !defined(OS2) && !defined(INIT_ONLY)) #ifndef WINDOWS_NT #ifndef __DDK_SRC__ sp = (SYSPARMS *)CaddiInit(InitBuf[iBoard], VideoBuf[iBoard]); if(BindingRC[iBoard] != (dword)NULL) { dword _Far *pBufBind; pBufBind = BufBind; *pBufBind++ = INITRC; *pBufBind++ = (dword)BindingRC[iBoard]; *pBufBind++ = SETENDPOINT + (0x1 << 16); *pBufBind++ = (dword)BindingRC[iBoard]; *pBufBind++ = DONE; if (!mtxPostBuffer (BufBind, DONT_CARE, DONT_CARE)) return(mtxFAIL); } #else sp = (SYSPARMS *)InitDDK(InitBuf[iBoard], VideoBuf[iBoard]); /*** *** _tDDK_STATE needs to be re-initialized here if you want the DDK *** to behave exactly like the SDK ***/ #endif /* __DDK_SRC__ */ #endif /* #ifndef WINDOWS_NT */ #endif /* #if( !defined(_WINDOWS_DLL16) && !defined(OS2))... */ return(mtxOK); } /*---------------------------------------------------------- * blkModeSupported * * Check if board support 8-bit block mode. * Condition: i) chip set ATHENA * ii) IMP+ PCB rev 2 or more * iii) * * Return: * mtxOK : 8-bit block mode supported * mtxFAIL : 8-bit block mode not supported * *----------------------------------------------------------*/ bool blkModeSupported() { dword TramDword; /* Test if ATHENA chip */ if( ((Hw[iBoard].ProductRev >> 4) & 0x0000000f) < ATHENA_CHIP) return mtxFAIL; /* Special case */ if( ((Hw[iBoard].ProductType & 0x0f) == BOARD_MGA_RESERVED) && (Hw[iBoard].DacType != TVP3026 ) ) return mtxFAIL; /* Test IMP+ with PCB rev < 2, we read TramDword to find IMP+ /p4 */ mgaReadDWORD(*(pMgaBaseAddr+TITAN_OFFSET+TITAN_OPMODE),TramDword); TramDword &= TITAN_TRAM_M; /* PCB rev < 2 and not a /p4 */ if( (((Hw[iBoard].ProductRev & 0xf) < 2) && !TramDword)) return mtxFAIL; return mtxOK; } /*---------------------------------------------------------- * mtxSetDisplayMode * * Select the display mode * * Return: * ptr != 0 : Start address of the vidset buffer * ptr = 0 : SetDisplayMode select failure * *----------------------------------------------------------*/ bool mtxSetDisplayMode(HwModeData *pDisplayModeSelect, dword Zoom) { byte TmpByte, vsyncPresent; dword TmpDword; dword Dst0, Dst1, i; dword InfoHardware; /*-----------------------------------------------------------*/ #ifdef PRINT_DEBUG { reOpenDebugfFile(); debug_printf("****** SetDisplayMode\n"); } #endif if (Hw[iBoard].pCurrentHwMode == NULL) { #ifdef PRINT_DEBUG closeDebugfFile("Hw[iBoard].pCurrentHwMode == NULL Fail\n"); #endif return(mtxFAIL); } /* Validate Display mode to see if it is <= Hard Mode */ if (pDisplayModeSelect->DispWidth > Hw[iBoard].pCurrentHwMode->DispWidth) { #ifdef PRINT_DEBUG closeDebugfFile("pDisplayModeSelect->DispWidth > Hw[iBoard].pCurrentHwMode->DispWidth Fail\n"); #endif return(mtxFAIL); } /* Validate pDisplayModeSelect to see if it is displayable */ if (pDisplayModeSelect->DispType & DISP_NOT_SUPPORT) { #ifdef PRINT_DEBUG closeDebugfFile("DISPLAY_NOT_SUPPORT Fail\n"); #endif return(mtxFAIL); } if(pDisplayModeSelect->DispType & 0x08) /* 565 mode */ *((byte*) (InitBuf[iBoard] + INITBUF_565Mode)) = TRUE; else *((byte*) (InitBuf[iBoard] + INITBUF_565Mode)) = FALSE; Hw[iBoard].pCurrentDisplayMode = NULL; mtxSetVideoMode(mtxADV_MODE); /* begin programmation of display in vsynch */ /* Test blank screen */ mgaWriteBYTE(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_SEQ_ADDR), 0x01); mgaReadBYTE(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_SEQ_DATA), vsyncPresent); vsyncPresent = !(vsyncPresent & 0x20); /* Test if valide horizontal parameters in CRTC */ if (vsyncPresent) { mgaWriteBYTE(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_1_CRTC_ADDR), 0x00); mgaReadBYTE(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_1_CRTC_DATA), TmpByte); mgaWriteBYTE(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_1_CRTC_ADDR), 0x01); mgaReadBYTE(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_1_CRTC_DATA), vsyncPresent); /* Compare Hdisplay Htotal */ vsyncPresent = vsyncPresent < TmpByte; } if (vsyncPresent) { for (i = 0; i < 1000000L; i++) { mgaReadDWORD(*(pMgaBaseAddr + TITAN_OFFSET + TITAN_STATUS), TmpDword); if ( !(TmpDword & TITAN_VSYNCSTS_M) ) break; } for (i = 0; i < 1000000L; i++) { mgaReadDWORD(*(pMgaBaseAddr + TITAN_OFFSET + TITAN_STATUS), TmpDword); if ( (TmpDword & TITAN_VSYNCSTS_M) ) break; } } /*------ Strap added in ATHENA For max clock dac support ----*/ GetMGAConfiguration(pMgaBaseAddr, &Dst0, &Dst1, &InfoHardware); mgaReadDWORD(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_CONFIG), InfoHardware); if(!((Dst1 & TITAN_DST1_200MHZ_M) >> TITAN_DST1_200MHZ_A)) InfoHardware = InfoHardware & 0xfffffffb; /* bit 2=0: Board supports regular (135MHz/170MHz) operation */ else InfoHardware = InfoHardware | 0x00000004; /* bit 2=1: Board supports 200MHz operation */ mgaWriteDWORD(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_CONFIG), InfoHardware); /*------ Strap added for ATHENA ------------------------------*/ if ( blkModeSupported() ) { mgaReadDWORD(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_OPMODE), InfoHardware); if(Dst0 & TITAN_DST0_BLKMODE_M) InfoHardware = InfoHardware & 0xf7ffffff; /* bit 27=0: VRAM 4 bit block mode */ else InfoHardware = InfoHardware | 0x08000000; /* bit 27=1: VRAM 8 bit block mode */ mgaWriteDWORD(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_OPMODE), InfoHardware); } /* Blank the screen */ mgaWriteBYTE(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_SEQ_ADDR), 0x01); mgaReadBYTE(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_SEQ_DATA), TmpByte); TmpByte |= 0x20; /* screen off */ mgaWriteBYTE(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_SEQ_DATA), TmpByte); Hw[iBoard].pCurrentDisplayMode = pDisplayModeSelect; Hw[iBoard].CurrentZoomFactor = (Zoom & 0x000f000f); /*** Load video parameters, load values in vidtab[] ***/ loadVidPar(Zoom, Hw[iBoard].pCurrentHwMode, Hw[iBoard].pCurrentDisplayMode); /*** Calculate register values of the CRTC and put in crtcTab[] ***/ calculCrtcParam(); MoveToVideoBuffer((byte *)vidtab, (byte *)crtcTab, (byte *)VideoBuf[iBoard]); #ifdef PRINT_DEBUG imprimeBuffer(InitBuf[iBoard], VideoBuf[iBoard]); #endif #if 0 /*VIDEOPRO Init if TV MODE*/ if (pDisplayModeSelect->DispType & 0x02) { switch(pDisplayModeSelect->DispWidth) { default: case 640: if (VAFCconnector) initVideoMode(NTSC_STD | VAFC, (byte)pDisplayModeSelect->PixWidth); else initVideoMode(NTSC_STD, (byte)pDisplayModeSelect->PixWidth); break; case 768: if (VAFCconnector) initVideoMode(PAL_STD | VAFC, (byte)pDisplayModeSelect->PixWidth); else initVideoMode(PAL_STD, (byte)pDisplayModeSelect->PixWidth); break; } } #endif MGAVidInit(InitBuf[iBoard], VideoBuf[iBoard]); #if 0 /*VIDEOPRO Make on if TV mode off sinon */ if (pDisplayModeSelect->DispType & 0x02) { if (VAFCconnector) initVideoPro(1, PX2085); else initVideoPro(1, Hw[iBoard].DacType); } else { initVideoPro(0, Hw[iBoard].DacType); } #endif #ifdef SCRAP /*** BEN TEST SPECIAL POUR VIDEOPRO ***/ mgaReadBYTE(*(pMgaBaseAddr+TITAN_OFFSET+TITAN_MISC_OUT_R), TmpByte); TmpByte = TmpByte & 0xfb; /* force bit 2 a 0 (clock) */ mgaWriteBYTE(*(pMgaBaseAddr+TITAN_OFFSET+TITAN_MISC_OUT_W), TmpByte); mgaReadBYTE(*(pMgaBaseAddr+TITAN_OFFSET+TITAN_CRT_CTRL),TmpByte); TmpByte |= 0xc0; /* Set vertical and horizontal reset */ mgaWriteBYTE(*(pMgaBaseAddr+TITAN_OFFSET+TITAN_CRT_CTRL),TmpByte); if(pDisplayModeSelect->DispType & 0x02 ) /* mode TV */ initVideoPro(1); else initVideoPro(0); #endif /*** BEN pour Pedro ***/ /* Flag to avoid multiple initialisation of lvid[0:2] and lvidfield */ *((byte*)(VideoBuf[iBoard] + VIDEOBUF_LvidInitFlag)) |= 0x80; #if( !defined(_WINDOWS_DLL16) && !defined(OS2) && !defined(INIT_ONLY)) #ifndef WINDOWS_NT /*** BEN Permet de determiner DBWindowXOffset et DBWindowYOffset ***/ #ifndef __DDK_SRC__ sp = (SYSPARMS *)CaddiInit(InitBuf[iBoard], VideoBuf[iBoard]); #else sp = (SYSPARMS *)InitDDK(InitBuf[iBoard], VideoBuf[iBoard]); #endif #endif #endif #ifdef _WINDOWS_DLL16 if(NbSxciLoaded) { fp1 = (FARPROC2)GetProcAddress(hsxci, "Win386LibEntry"); (*fp1)((byte _Far *)InitBuf[iBoard], (byte _Far *)VideoBuf[iBoard], Hw[iBoard].pCurrentHwMode->FbPitch, ID_CallCaddiInit); } #endif /* Unblank the screen */ mgaWriteBYTE(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_SEQ_ADDR), 0x01); mgaReadBYTE(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_SEQ_DATA), TmpByte); TmpByte &= 0xdf; /* screen on */ mgaWriteBYTE(*(pMgaBaseAddr+TITAN_OFFSET + TITAN_SEQ_DATA), TmpByte); /* Wait for start of vertical sync */ mgaPollDWORD(*(pMgaBaseAddr + TITAN_OFFSET + TITAN_STATUS), TITAN_VSYNCSTS_SET, TITAN_VSYNCSTS_M); /* Need 16 ms for be sure we are one retrace make */ /* ------------------------------ Remplace par un delai de 16 ms */ /* delay_us(16000); */ /*** Calculation of CurrentOverScanX and CurrentOverScanY in structure HwData ***/ if ( ((Hw[iBoard].ProductRev >> 4) & 0x0000000f) > 0 ) /* NOT TITAN */ { Hw[iBoard].CurrentOverScanX = 0; Hw[iBoard].CurrentOverScanY = 0; } else { overScan(); } #if( !defined(WINDOWS) && !defined(OS2) && !defined(WINDOWS_NT) && !defined(INIT_ONLY)) mtxScClip(0, 0, pDisplayModeSelect->DispWidth, pDisplayModeSelect->DispHeight); #endif #ifdef _WINDOWS_DLL16 if(NbSxciLoaded) { *(pDllMem+PAN_DISP_WIDTH) = Hw[iBoard].pCurrentDisplayMode->DispWidth-1; *(pDllMem+PAN_DISP_HEIGHT) = Hw[iBoard].pCurrentDisplayMode->DispHeight-1; switch((Zoom & 0x000f000f)) { case(0x00010001): *(pDllMem+DB_SCALE) = (word)1; break; case(0x00020002): *(pDllMem+DB_SCALE) = (word)2; break; case(0x00040004): *(pDllMem+DB_SCALE) = (word)4; break; default: *(pDllMem+DB_SCALE) = (word)1; } AdjustDBWindow(); } #endif /* #ifdef _WINDOWS_DLL16 */ #ifdef PRINT_DEBUG closeDebugfFile("Fin Set Display Mode\n"); #endif return(mtxOK); } /*----------------------- Ajustement overscan ------------------------------ hblank_e n'a que 6 bits de resolution. On le construit comme suit 5 bits Lsb dans reg 3 <4:0> et 6ieme bit dans reg 5 <7> horizontal blank end = (reg 3 & 0x1f) | ((reg 5 >> 2) & 0x20) On complete les bits manquant de BlankEnd en utilisant les bits <7:6> de BLANK START. SI les 6 bits LSBs de BLANK START sont superieur a ceux du BLANK END alors ceci veu dire les deux les plus significatif de BLANK END sont egale a ceux du BLANK START + 1, sinon il sont egaux. Une fois qu'on a le BLANK END complet on peut le comparer au horizontal Total pour connaitre l'overscan a gauche. 0.......Blank End....Htotal - 1. Note: On compare a Htotal -1. si il y 10 caractere alors on va de 0...9 Idem pour l'overscan vertical ou il manque les 2 bits MSBs <9:8>. Note: Il y a un cas special ou le HBLANKE est a zero, dans ce cas l'overscan doit-etre a zero. ----------------------------------------------------------------------------*/ static void overScan(void) { word total, blank_s, blank_e, mask; /* Overlay to left of screen */ /* Htotal = reg(0) + 5 donc Htotal - 1 = reg(0) + 4 */ total = (word)(crtcTab[0] + 4); blank_s = (word)crtcTab[2]; blank_e = (word)((crtcTab[3] & 0x1f) | ( (crtcTab[5] >> 2) & 0x20 )); if (blank_e != 0) /* We verify for the special case where blank_e == 0 */ { mask = blank_s >> 6; if ((blank_s & 0x3f) > blank_e) mask++; blank_e |= mask << 6; Hw[iBoard].CurrentOverScanX = (total - blank_e) << 3; /* 8 pixel per cell */ } else { Hw[iBoard].CurrentOverScanX = 0; } /* Overlay on top of screen */ /* Vtotal = reg(6,7) + 2 donc Vtotal - 1 = reg(6,7) + 1 */ total = (word)crtcTab[6] + 1; mask = (word)crtcTab[7]; total |= ((mask << 4) & 0x200) | ((mask << 8) & 0x100); blank_s = (word)crtcTab[21] | ( ((word)crtcTab[9] << 4) & 0x200 ) | ( ((word)crtcTab[7] << 5) & 0x100 ) ; blank_e = (word)crtcTab[22]; mask = blank_s >> 8; if ((blank_s & 0x7f) > blank_e) mask++; blank_e |= mask << 8; Hw[iBoard].CurrentOverScanY = (total - blank_e); /* Test if we double the scan lines (Horizontal retrace divide select) */ if (crtcTab[23] & 0x04) Hw[iBoard].CurrentOverScanY <<= 1; /* We modify the overscan, must recalculate the HotSpot */ if (Hw[iBoard].cursorInfo.CurWidth > 0) mtxCursorSetHotSpot(Hw[iBoard].cursorInfo.cHotSX, Hw[iBoard].cursorInfo.cHotSX); } void mapPciVl(dword addr) { byte TmpByte; dword pci_id, TmpDword; mgaReadDWORD(*(pMgaBaseAddr+0x2000),pci_id); if ((pci_id == (dword)0x0518102b) || (pci_id == (dword)0x0d10102b)) { mgaWriteDWORD(*(pMgaBaseAddr+0x2010),addr); mgaReadBYTE(*(pMgaBaseAddr+0x2004), TmpByte); mgaWriteBYTE(*(pMgaBaseAddr+0x2004), TmpByte | 2); mgaReadDWORD(*(pMgaBaseAddr+TITAN_OFFSET+TITAN_CONFIG),TmpDword); if (TmpDword&TITAN_VGAEN_M) { #ifndef WINDOWS_NT _outp(0x46e8, 0x08); #else _outp(ADDR_46E8_PORT, 0x08); #endif } } } /*------------------------------------------------------------------- * MapBoard * * Map all MGA devices in systems * * Set global variables: * - Hw[].MapAddress * - MgaSel : Board selector *-------------------------------------------------------------------*/ bool MapBoard(void) { dword val_id, ba; #if USE_VP_GET_ACCESS_RANGES VIDEO_ACCESS_RANGE MgaDriverPciAccessRange[14]; ULONG ulNbPciAccessRanges = 14; VP_STATUS status; USHORT VendorId = MATROX_VENDOR_ID; USHORT DeviceId[] = { MGA_DEVICE_ID_ATH, MGA_DEVICE_ID_ATL }; ULONG ulNbDeviceIds = 2; ULONG ulDeviceCnt = 0; ULONG k; BOOLEAN bRangeFound; #endif //[dlee] For now, we'll just check base addresses AC000 and C8000 on Alpha //#ifndef MGA_ALPHA dword ScanAddr[] = { MGA_ISA_BASE_1, MGA_ISA_BASE_2, MGA_ISA_BASE_3, MGA_ISA_BASE_4, MGA_ISA_BASE_5, MGA_ISA_BASE_6, MGA_ISA_BASE_7 }; //#else // dword ScanAddr[] = { MGA_ISA_BASE_2, MGA_ISA_BASE_1 }; //#endif word i, j, b_exist; PciBiosInfo bi; #ifndef WINDOWS_NT NbBoard = 0; #endif MgaSel = getmgasel(); mtxSetVLB(MgaSel); #ifdef WINDOWS_NT // Special if (NtInterfaceType == PCIBus) { #endif #if USE_VP_GET_ACCESS_RANGES #define PCI_SLOT_MAX 32 for (i = 0; i < (word)ulNbPciAccessRanges; i++) { MgaDriverPciAccessRange[i].RangeStart.LowPart = 0xffffffff; } // DbgBreakPoint(); // _asm {int 3} PciSlot = 0; status = VideoPortGetAccessRanges(pMgaDeviceExtension, 0, (PIO_RESOURCE_DESCRIPTOR) NULL, ulNbPciAccessRanges, MgaDriverPciAccessRange, &VendorId, &DeviceId[ulDeviceCnt], &PciSlot); if (status == NO_ERROR) { VideoDebugPrint((1, "MGA: no_error on DeviceId %d\n", ulDeviceCnt)); i = 0; while ((i < (word)ulNbPciAccessRanges) && (NbBoard < 7) && ((ba = MgaDriverPciAccessRange[i].RangeStart.LowPart) != 0xffffffff)) { if (MgaDriverPciAccessRange[i].RangeLength == 0x4000) { // This is a control aperture. // Do we already know about it? bRangeFound = FALSE; for (k = 0; k < NbBoard; k++) { if (Hw[k].MapAddress == ba) { bRangeFound = TRUE; break; } } if (!bRangeFound) { // This is a new memory-space range. if ((pMgaBaseAddr = setmgasel(MgaSel, ba, 4)) != NULL) { mgaReadDWORD(*(pMgaBaseAddr+TITAN_OFFSET+TITAN_REV), val_id); if ( (val_id & (~TITAN_CHIPREV_M)) == TITAN_ID) { // This is one of ours! Hw[NbBoard].MapAddress = ba; Hw[NbBoard].BaseAddress = pMgaBaseAddr; MgaBusType[NbBoard] = MGA_BUS_PCI; NbBoard++; } else { // We don't know what this was! Free the range. VideoPortFreeDeviceBase(pMgaDeviceExtension, pMgaBaseAddr); } } } } MgaDriverPciAccessRange[i].RangeStart.LowPart = 0xffffffff; i++; } } else { if (status == ERROR_MORE_DATA) VideoDebugPrint((1, "MGA: error_more_data on DeviceId %d\n", ulDeviceCnt)); else if (status == ERROR_DEV_NOT_EXIST) VideoDebugPrint((1, "MGA: error_dev_not_exist on DeviceId %d\n", ulDeviceCnt)); else VideoDebugPrint((1, "MGA: unknown error on DeviceId %d\n", ulDeviceCnt)); } #else /* #if USE_VP_GET_ACCESS_RANGES */ #ifdef WINDOWS_NT /* For WinNT3.1 and WinNT3.5/Intel */ // Get access to ports before calling pciFindFirstMGA_2. //if (VideoPortVerifyAccessRanges(pMgaDeviceExtension, // 1, // &MgaPciCseAccessRange) == NO_ERROR && // (pMgaPciIo = VideoPortGetDeviceBase(pMgaDeviceExtension, // MgaPciCseAccessRange.RangeStart, // MgaPciCseAccessRange.RangeLength, // MgaPciCseAccessRange.RangeInIoSpace)) != NULL) if ((pMgaPciIo = VideoPortGetDeviceBase(pMgaDeviceExtension, MgaPciCseAccessRange.RangeStart, MgaPciCseAccessRange.RangeLength, MgaPciCseAccessRange.RangeInIoSpace)) != NULL) { #endif /* #ifdef MGA_WINNT31 */ #ifndef OS2 if ( (ba = (dword)pciFindFirstMGA_2()) != (dword)-1) { while ( (ba != (dword)-1 ) && (NbBoard < 7) ) { #ifdef WINDOWS_NT b_exist = 0; for (j = 0; j < NbBoard; j++) { if (Hw[j].MapAddress == ba) { b_exist = 1; break; } } if (!b_exist) { // This is a new range. #endif pMgaBaseAddr = setmgasel(MgaSel, ba, 4); if (pMgaBaseAddr != NULL) { mgaReadDWORD(*(pMgaBaseAddr+TITAN_OFFSET+TITAN_REV),val_id); if ( (val_id & (~TITAN_CHIPREV_M)) == TITAN_ID) { Hw[NbBoard].MapAddress = ba; #ifdef WINDOWS_NT Hw[NbBoard].BaseAddress = pMgaBaseAddr; MgaBusType[NbBoard] = MGA_BUS_PCI; Hw[NbBoard].ConfigSpace = configSpace - 0x100; if (configSpace > 0xd000) Hw[NbBoard].ConfigSpace = 0; #if 0 // TO BE COMPLETED if (Hw[NbBoard].ConfigSpace != 0) { MgaPciConfigAccessRange.RangeStart.LowPart = (ULONG)configSpace; if (VideoPortVerifyAccessRanges(pMgaDeviceExtension, 1, &MgaPciConfigAccessRange) == NO_ERROR && (pMgaPciConfigSpace = VideoPortGetDeviceBase(pMgaDeviceExtension, MgaPciConfigAccessRange.RangeStart, MgaPciConfigAccessRange.RangeLength, MgaPciConfigAccessRange.RangeInIoSpace)) != NULL) { Hw[NbBoard].ConfigSpaceAddress = pMgaPciConfigSpace; } } #endif #endif NbBoard++; } #ifdef WINDOWS_NT else { // We don't know what that was! VideoPortFreeDeviceBase(pMgaDeviceExtension, pMgaBaseAddr); } #endif } #ifdef WINDOWS_NT } #endif ba = (dword)pciFindNextMGA_2(); } } #ifdef WINDOWS_NT // Free access to ports after calling pciFindFirst/NextMGA_2. VideoPortFreeDeviceBase(pMgaDeviceExtension,pMgaPciIo); } #endif /* #ifdef WINDOWS_NT */ else { #ifdef WINDOWS_NT if ((pciBiosRoutine = pciBiosCallAddr()) != NULL) { VideoDebugPrint((1, "pciBiosRoutine = 0x%x\n", pciBiosRoutine)); #endif if ( pciBiosPresent( &bi ) ) { #endif /* #ifndef OS2 */ ba = (dword)pciFindFirstMGA(); while ( (ba != (dword)-1 ) && (NbBoard < 7) ) { #ifdef WINDOWS_NT b_exist = 0; for (j = 0; j < NbBoard; j++) { if (Hw[j].MapAddress == ba) { b_exist = 1; break; } } if (!b_exist) { // This is a new range. #endif pMgaBaseAddr = setmgasel(MgaSel, ba, 4); if (pMgaBaseAddr != NULL) { mgaReadDWORD(*(pMgaBaseAddr+TITAN_OFFSET+TITAN_REV), val_id); if ( (val_id & (~TITAN_CHIPREV_M)) == TITAN_ID) { Hw[NbBoard].MapAddress = ba; #ifdef WINDOWS_NT Hw[NbBoard].BaseAddress = pMgaBaseAddr; MgaBusType[NbBoard] = MGA_BUS_PCI; #endif NbBoard++; } #ifdef WINDOWS_NT else { // We don't know what that was! VideoPortFreeDeviceBase(pMgaDeviceExtension, pMgaBaseAddr); } #endif } #ifdef WINDOWS_NT } #endif ba = (dword)pciFindNextMGA(); } #ifndef OS2 } #ifdef WINDOWS_NT } #endif } #endif /* #ifndef OS2 */ #endif /* #if USE_VP_GET_ACCESS_RANGES */ #ifdef WINDOWS_NT // Special } else { #endif /* Search ISA BUS */ if ( mtxIsVLBBios() ) { #ifndef WINDOWS_NT _outp(0x46e8, 0x00); #else _outp(ADDR_46E8_PORT, 0x00); #endif } //#ifndef MGA_ALPHA for (i=0; (i < 7) && (NbBoard < 7); i++) //#else // for (i=0; (i < 2) && (NbBoard < 2); i++) //#endif { b_exist = 0; for (j = 0; j < NbBoard; j++) { if (Hw[j].MapAddress == ScanAddr[i]) { b_exist = 1; break; } } #ifdef WINDOWS_NT // On Windows NT, we have to verify that the range we're about to map // does not conflict with a range that has already been mapped by // another driver. //if ((!b_exist) && (!bConflictDetected(ScanAddr[i]))) if (!b_exist) { #endif pMgaBaseAddr = setmgasel(MgaSel, ScanAddr[i], 4); if (pMgaBaseAddr != NULL) { mapPciVl(ScanAddr[i]); mgaReadDWORD(*(pMgaBaseAddr+TITAN_OFFSET+TITAN_REV),val_id); if ( !b_exist && ((val_id & (~TITAN_CHIPREV_M)) == TITAN_ID)) { Hw[NbBoard].MapAddress = ScanAddr[i]; #ifdef WINDOWS_NT Hw[NbBoard].BaseAddress = pMgaBaseAddr; MgaBusType[NbBoard] = MGA_BUS_ISA; Hw[NbBoard].ConfigSpace = 0; #endif if ( mtxIsVLBBios() && (ScanAddr[i] == MGA_ISA_BASE_1) ) mgaWriteDWORD(*(pMgaBaseAddr+0x2010), (dword)0x80000000 | (dword)MGA_ISA_BASE_1); NbBoard++; } #ifdef WINDOWS_NT else { // We don't know what that was! VideoPortFreeDeviceBase(pMgaDeviceExtension, pMgaBaseAddr); } #endif } #ifdef WINDOWS_NT } #endif } #ifdef WINDOWS_NT // Special } #endif /* Indicates end of array */ Hw[NbBoard].MapAddress = (dword)-1; if (NbBoard == 0) return(mtxFAIL); else return(mtxOK); } /*----------------------------------------------------- * adjustDefaultVidset * * Return default Vidset for the select board *------------------------------------------------------*/ char *adjustDefaultVidset() { general_info *generalInfo; mgainf = DefaultVidset; generalInfo = (general_info *)selectMgaInfoBoard(); generalInfo->MapAddress = Hw[iBoard].MapAddress; #ifdef WINDOWS_NT generalInfo->BitOperation8_16 = -1; #else generalInfo->BitOperation8_16 = (short)0xffff; #endif return(mgainf); } //[dlee] Modified for Windows NT // This is not called for Windows NT because we can't open files in // kernel mode. (MGA.INF is new read in the user-mode driver instead) #ifndef WINDOWS_NT /*-------------------------------------------------------------- * mtxLectureMgaInf * * Read file mga.inf and put data in buffer mgainf * or take DefaultVidset * *--------------------------------------------------------------*/ bool mtxLectureMgaInf(void) { #ifdef WINDOWS LPSTR lpszEnv; bool findMGA; #endif #ifdef OS2 HFILE hFile; USHORT usAction; USHORT usInfoLevel = 1; FILESTATUS status; USHORT bytesRead; ULONG fn_ID; char mgaName[] = "MGA"; char far *mgaPathPtr; char mgaPath[300]; USHORT fileSize; #else FILE *pFile; char *env, path[128]; long fileSize; #endif int i; #ifndef OS2 /*** Reading file MGA.INF ***/ /*** Put values in global array mgainf ***/ strcpy(path, "mga.inf"); if ((pFile = fopen(path, "rb")) == NULL) { #endif #ifdef WINDOWS /*** Find MGA variable ***/ findMGA = FALSE; lpszEnv = GetDOSEnvironment(); while(*lpszEnv != '\0') { if (! (strncmp("MGA=", lpszEnv, 4)) ) { findMGA = TRUE; break; } lpszEnv += lstrlen(lpszEnv) + 1; } if (findMGA) { strcpy(path, lpszEnv+4); i = strlen(path); if (path[i-1] != '\\') strcat(path, "\\"); strcat(path, "mga.inf"); if ((pFile = fopen(path, "rb")) == NULL) { mgainf = adjustDefaultVidset(); return mtxOK; } } else { mgainf = adjustDefaultVidset(); return mtxOK; } #endif /* #ifdef WINDOWS */ #if( !defined(WINDOWS) && !defined(OS2) && !defined(WINDOWS_NT) ) /* Check environment variable MGA */ if ( (env = getenv("MGA")) != NULL ) { strcpy(path, env); i = strlen(path); if (path[i-1] != '\\') strcat(path, "\\"); strcat(path, "mga.inf"); if ((pFile = fopen(path, "rb")) == NULL) { mgainf = adjustDefaultVidset(); return mtxOK; } } else { mgainf = adjustDefaultVidset(); return mtxOK; } #endif /* #if( !defined(WINDOWS) && !defined(OS2) && !defined(WINDOWS_NT) ) */ #ifdef OS2 /* Position of mga.inf defined by the environnement variable MGA */ /* if it is not defined, we will use the setup by defaut */ if(DosScanEnv(mgaName, &mgaPathPtr)) { mgainf = adjustDefaultVidset(); return(mtxOK); } strcpy(mgaPath, mgaPathPtr); strcat(mgaPath, "\\mga.inf"); if(DosOpen2(mgaPath, &hFile, &usAction, 0L, FILE_NORMAL, FILE_OPEN, OPEN_ACCESS_READONLY | OPEN_SHARE_DENYREADWRITE, NULL, 0L)) { mgainf = adjustDefaultVidset(); return(mtxOK); } DosQFileInfo(hFile, usInfoLevel, &status, (USHORT)sizeof(FILESTATUS)); fileSize = (USHORT)status.cbFile; #else } fseek(pFile, 0, SEEK_END); fileSize = ftell(pFile); rewind(pFile); #endif if (CheckHwAllDone && (mgainf != DefaultVidset)) free( (void *)mgainf); if ( (mgainf = (char *)malloc(fileSize * sizeof(char))) == 0 ) { #ifdef OS2 DosClose(hFile); #else fclose(pFile); #endif mgainf = adjustDefaultVidset(); /*** BEN setter un warning code ici ***/ return(mtxOK); } #ifdef OS2 if ( DosRead(hFile, (PVOID)mgainf, fileSize, &bytesRead) || (bytesRead != fileSize)) #else if ( fread(mgainf, sizeof(char), fileSize, pFile) < fileSize ) #endif { #ifdef OS2 DosClose(hFile); #else fclose(pFile); #endif free(mgainf); mgainf = adjustDefaultVidset(); /*** BEN setter un warning code ici ***/ return(mtxOK); } if ( ((header *)mgainf)->Revision != (short)VERSION_NUMBER) { /* Conversion of old mga.inf file to the current revision */ if ( !(mgainf = mtxConvertMgaInf( mgainf ))) { #ifdef OS2 DosClose(hFile); #else fclose(pFile); #endif mgainf = adjustDefaultVidset(); /*** BEN setter un warning code ici ***/ return(mtxOK); } } #ifdef OS2 DosClose(hFile); #else fclose(pFile); #endif if ( (general_info *)selectMgaInfoBoard() == NULL) { free(mgainf); mgainf = adjustDefaultVidset(); /*** BEN setter un warning code ici ***/ return(mtxOK); } if (strncmp(mgainf, "Matrox MGA Setup file", 21)) { free(mgainf); mgainf = adjustDefaultVidset(); } return(mtxOK); } #endif /* #ifndef WINDOWS_NT */ /*----------------------------------------------------- * selectMgaInfoBoard * * Return a pointer at the first information for the * selected board *------------------------------------------------------ * * Algorithme de recherche * mga.inf support 7 card in the system. We have to fit the MapAdress * of the card whith the one specified in structure general_info. If * no one of the seven general_info fit, we pick the first valid one. * Note : The map adresse of the structure is not updated, we must not use * this adress outside this function. * *------------------------------------------------------*/ char *selectMgaInfoBoard() { word IndexBoard, DefaultBoard; header *pHeader = (header *)mgainf; general_info *genInfo = NULL; DefaultBoard = NB_BOARD_MAX; for (IndexBoard = 0; !genInfo && (IndexBoard < NB_BOARD_MAX); IndexBoard++) { if ( pHeader->BoardPtr[IndexBoard] > 0 ) { if ( DefaultBoard == NB_BOARD_MAX) DefaultBoard = IndexBoard; genInfo = (general_info *)(mgainf + pHeader->BoardPtr[IndexBoard]); if (Hw[iBoard].MapAddress != genInfo->MapAddress) genInfo = NULL; } } if ( !genInfo) /*** BEN setter un warning code ici ***/ { if (DefaultBoard < NB_BOARD_MAX) { genInfo = (general_info *)(mgainf + pHeader->BoardPtr[DefaultBoard]); } else { mgainf = adjustDefaultVidset(); pHeader = (header *)mgainf; genInfo = (general_info *)(mgainf + pHeader->BoardPtr[0]); } } return (char *)genInfo; } /*----------------------------------------------------- * UpdateHwModeTable * * Update hardware mode table with interlace informations * if we are in interlace mode * *------------------------------------------------------*/ void UpdateHwModeTable (char *pMgaInfo, HwModeData *pHwMode, HwModeInterlace *piHwMode, bool dacSupportHires ) { short FlagMonitorSupport; word TmpRes; HwModeData *pHwMode1; general_info *generalInfo = (general_info *)pMgaInfo; if (CheckHwAllDone) { for (pHwMode1 = pHwMode ; pHwMode1->DispWidth != (word)-1; pHwMode1++) { pHwMode1->DispType &= 0x5e; /* force interlaced = 0 and monitor limited = 0 */ if (pHwMode1->DispType & 0x40) /* Hw limited */ pHwMode1->DispType |= 0x80; /* force not displayable bit on */ } } for ( ; pHwMode->DispWidth != (word)-1; piHwMode++, pHwMode++) { /* Determine TmpRes for compatibility with spec mga.inf */ switch (pHwMode->DispWidth) { case 640: if (pHwMode->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; } FlagMonitorSupport = generalInfo ->MonitorSupport[TmpRes]; /*** Update of the pHwMode table if I (interlace) ***/ switch ( FlagMonitorSupport ) { case MONITOR_I: if(piHwMode->FbPitch) { pHwMode->FbPitch = piHwMode->FbPitch; pHwMode->DispType = piHwMode->DispType; pHwMode->NumOffScr = piHwMode->NumOffScr; pHwMode->pOffScr = piHwMode->pOffScr; } pHwMode->DispType |= DISP_SUPPORT_I; /* Interlace */ break; case MONITOR_NA: pHwMode->DispType |= DISP_SUPPORT_NA; /* monitor limited */ break; } /* Not displayable, hw limited */ if ((pHwMode->DispWidth > 1280) && !dacSupportHires) pHwMode->DispType |= DISP_SUPPORT_HWL; #if ((!defined (WINDOWS_NT)) || (USE_DDC_CODE)) if (SupportDDC && !(byte)InDDCTable(pHwMode->DispWidth)) pHwMode->DispType |= DISP_SUPPORT_NA; /* monitor limited */ #endif /*** For ATLAS chip we can't do Z buffering ***/ if( ((Hw[iBoard].ProductRev >> 4) & 0x0000000f) == ATLAS_CHIP && pHwMode->ZBuffer ) pHwMode->DispType |= DISP_SUPPORT_HWL; /*** For an Ultima board we can't do Z-buffer ***/ if( !((Dst1 & TITAN_DST1_ABOVE1280_M) && (Dst1 & TITAN_DST1_200MHZ_M)) && (ProductMGA[iBoard] == MGA_PCI_2M || ProductMGA[iBoard] == MGA_PCI_4M) && ((Hw[iBoard].ProductRev >> 4) & 0x0000000f) == ATHENA_CHIP && pHwMode->ZBuffer && Hw[iBoard].DacType != TVP3026) { pHwMode->DispType |= DISP_SUPPORT_HWL; } /* For Impression Lite we can't do double buffering */ if ((Dst1 & TITAN_DST1_ABOVE1280_M) && (Dst1 & TITAN_DST1_200MHZ_M) && ((Hw[iBoard].ProductRev >> 4) & 0x0000000f) == ATHENA_CHIP && (pHwMode->DispType & 0x10) && pHwMode->ZBuffer) { pHwMode->DispType |= DISP_SUPPORT_HWL; } /* PACK PIXEL ON TVP and Windows only */ #ifdef _WINDOWS_DLL16 if ((pHwMode->PixWidth == 24) && (Hw[iBoard].DacType != TVP3026)) pHwMode->DispType |= DISP_SUPPORT_HWL; #else if (pHwMode->PixWidth == 24) pHwMode->DispType |= DISP_SUPPORT_HWL; #endif } } /*----------------------------------------------------- * mtxGetMgaSel * * Return the selector * (Called by the driver) *------------------------------------------------------*/ dword mtxGetMgaSel(void) { return(MgaSel); } /*----------------------------------------------------- * mtxGetInfo * * Return useful informations to Open GL and Windows *------------------------------------------------------*/ void mtxGetInfo(HwModeData **pCurHwMode, HwModeData **pCurDispMode, byte **InitBuffer, byte **VideoBuffer) { *pCurHwMode = Hw[iBoard].pCurrentHwMode; *pCurDispMode = Hw[iBoard].pCurrentDisplayMode; *InitBuffer = InitBuf[iBoard]; *VideoBuffer = VideoBuf[iBoard]; } #ifdef WINDOWS /*----------------------------------------------------- * mtxGetHwData * * Return useful informations to Open GL and Windows * Return value: * - null pointer : no MGA board * - valid pointer: pointer to HwData structure *------------------------------------------------------*/ HwData *mtxGetHwData(void) { if(Hw[iBoard].MapAddress == (dword)-1) return 0; else return(&Hw[iBoard]); } #endif /* #ifdef WINDOWS */ /*----------------------------------------------------- * InitHwStruct * * Initialize: Hw[].pCurrentHwMode * Hw[].VramAvailable * Hw[].DramAvailable *------------------------------------------------------*/ bool InitHwStruct(byte CurBoard, HwModeData *pHwModeData, word sizeArray, dword VramAvailable, dword DramAvailable) { /* Dynamic allocation of memory if we have more than 1 board */ if (NbBoard == 1) { Hw[CurBoard].pCurrentHwMode = pHwModeData; } else { #ifdef WINDOWS_NT if(! (Hw[CurBoard].pCurrentHwMode = AllocateSystemMemory(sizeArray))) return mtxFAIL; Hw[CurBoard].pHwMode = Hw[CurBoard].pCurrentHwMode; #else if(! (Hw[CurBoard].pCurrentHwMode = malloc(sizeArray))) return mtxFAIL; #endif memcpy(Hw[CurBoard].pCurrentHwMode, pHwModeData, sizeArray); } FirstMode[CurBoard] = Hw[CurBoard].pCurrentHwMode; Hw[CurBoard].VramAvail = VramAvailable; Hw[CurBoard].DramAvail = DramAvailable; return mtxOK; } /*------------------------------------------------------------------- * mtxSetLUT * * Initialize RAMDAC LUT * * Return value: * mtxOK - successfull * mtxFAIL - failed (not in a LUT mode *-------------------------------------------------------------------*/ bool mtxSetLUT(word index, mtxRGB color) { if(! (Hw[iBoard].pCurrentHwMode->DispType & 0x04)) return mtxFAIL; switch(Hw[iBoard].DacType) { case BT482: mgaWriteBYTE(*(pMgaBaseAddr + RAMDAC_OFFSET + BT482_WADR_PAL), (byte)index); mgaWriteBYTE(*(pMgaBaseAddr + RAMDAC_OFFSET + BT482_COL_PAL), (byte)color); mgaWriteBYTE(*(pMgaBaseAddr + RAMDAC_OFFSET + BT482_COL_PAL), (byte)(color >> 8)); mgaWriteBYTE(*(pMgaBaseAddr + RAMDAC_OFFSET + BT482_COL_PAL), (byte)(color >> 16)); break; case BT485: case PX2085: case VIEWPOINT: case TVP3026: mgaWriteBYTE(*(pMgaBaseAddr + RAMDAC_OFFSET + BT484_WADR_PAL), (byte)index); mgaWriteBYTE(*(pMgaBaseAddr + RAMDAC_OFFSET + BT484_COL_PAL), (byte)color); mgaWriteBYTE(*(pMgaBaseAddr + RAMDAC_OFFSET + BT484_COL_PAL), (byte)(color >> 8)); mgaWriteBYTE(*(pMgaBaseAddr + RAMDAC_OFFSET + BT484_COL_PAL), (byte)(color >> 16)); break; default: return mtxFAIL; } return mtxOK; } /*--------------------------------------------- * mtxClose * Supported for compatibility. Nothing done *---------------------------------------------*/ void mtxClose(void) { } #ifdef _WINDOWS_DLL16 /*---------------------------------------------------------- * mtxLoadSXCI * * Load SXCI.DLL * * Return: (mtxOK or mtxFAIL) * *----------------------------------------------------------*/ HANDLE FAR PASCAL _export mtxLoadSXCI(word mode, word FAR *ErrorCode) { char cBuffer[20]; GetPrivateProfileString("mga.drv","3D","",cBuffer,sizeof(cBuffer), "SYSTEM.INI"); if( (strcmp(cBuffer,"OFF")== 0) && mode == SXCI_3D && (((Hw[iBoard].ProductRev >> 4) & 0x0000000f) == 0) ) /* TITAN */ { *ErrorCode = 101; return(0); } GetPrivateProfileString("boot","display.drv","",cBuffer,sizeof(cBuffer), "SYSTEM.INI"); if( (strcmp(cBuffer,"mga16.drv")== 0) && mode == SXCI_3D ) { *ErrorCode = 103; /* driver not supported */ return(0); } if( (Hw[iBoard].pCurrentHwMode->ZBuffer == FALSE) && mode == SXCI_3D) { *ErrorCode = 102; return(0); } /*** If pack pixel mode: can't load sxci.dll ***/ if( Hw[iBoard].pCurrentHwMode->PixWidth == 24) { *ErrorCode = 104; return(0); } hsxci = LoadLibrary("sxci.dll"); if(hsxci > 32) { fp1 = (FARPROC2)GetProcAddress(hsxci, "Win386LibEntry"); } else { *ErrorCode = 100; return(0); } pDllMem = (word FAR *)memalloc(30); (*fp1)(pDllMem, 31); /* Call PassPoolMem */ *(pDllMem+PAN_X) = 0; *(pDllMem+PAN_Y) = 0; *(pDllMem+PAN_DISP_WIDTH) = Hw[iBoard].pCurrentDisplayMode->DispWidth-1; *(pDllMem+PAN_DISP_HEIGHT) = Hw[iBoard].pCurrentDisplayMode->DispHeight-1; *(pDllMem+PAN_BOUND_LEFT) = 0; *(pDllMem+PAN_BOUND_RIGHT) = 0; *(pDllMem+PAN_BOUND_TOP) = 0; *(pDllMem+PAN_BOUND_BOTTOM) = 0; *(pDllMem+DB_SCALE) = (word)1; *ErrorCode = hsxci; NbSxciLoaded++; return(hsxci); } /*---------------------------------------------------------- * mtxUnloadSXCI * * Unload SXCI.DLL * * Return: void * *----------------------------------------------------------*/ void FAR PASCAL _export mtxUnloadSXCI(void) { if(NbSxciLoaded) { if(NbSxciLoaded == 1) memfree((void FAR **)&pDllMem); FreeLibrary(hsxci); NbSxciLoaded--; } } #endif /* #ifdef _WINDOWS_DLL16 */ /*---------------------------------------------------------- * ProgrammeClock * * Set clock according of new strapping: (50MHz, 55MHz or 60MHz) * VD34, VD33 -> MGA-PCI/2 and MGA-VLB/2 * VD49, VD36 -> MGA-PCI/2+ and MGA-VLB/2+ * * For TITAN -> 45MHz *----------------------------------------------------------*/ bool ProgrammeClock(byte Chip, dword Dst1, dword InfoDac) { dword Value; dword ValClock; byte TmpByte; if( (Chip == ATLAS_CHIP) || (Chip == ATHENA_CHIP)) { if ((Hw[iBoard].ProductType & 0x0f) == BOARD_MGA_RESERVED) { ValClock = 0x065AC3D; /* 50MHz */ } /*** Detect if MGA-PCI/2+ or MGA-VLB/2+ ***/ else if( ((ProductMGA[iBoard] == MGA_PCI_2M) || (ProductMGA[iBoard] == MGA_PCI_4M)) && (InfoDac == Info_Dac_ViewPoint)) { Value = ((Dst1 & TITAN_DST1_NOMUXES_M) >> (TITAN_DST1_NOMUXES_A-1)) | ((Dst1 & TITAN_DST1_ABOVE1280_M) >> TITAN_DST1_ABOVE1280_A); switch(Value) { case 3: ValClock = 0x065AC3D; /* 50MHz */ break; case 2: ValClock = 0x068A413; /* 60MHz */ break; case 0: ValClock = 0x067D83D; /* 55MHz */ break; default: return(mtxFAIL); } } else { Value = (Dst1 & TITAN_DST1_RAMSPEED_M) >> TITAN_DST1_RAMSPEED_A; switch(Value) { case 0: ValClock = 0x065AC3D; /* 50MHz */ break; case 1: ValClock = 0x068A413; /* 60MHz */ break; case 3: ValClock = 0x067D83D; /* 55MHz */ break; default: return(mtxFAIL); } } } else /* TITAN */ { ValClock = 0x0063AC44; /* 45MHz */ } /* Lookup for find real frequency to progrmming */ switch( ValClock ) { case 0x063AC44: presentMclk[iBoard] = 45000000L; /* 45Mhz */ break; case 0x065AC3D: presentMclk[iBoard] = 50000000L; /* 50Mhz */ break; case 0x067D83D: presentMclk[iBoard] = 55000000L; /* 55Mhz */ break; case 0x068A413: presentMclk[iBoard] = 60000000L; /* 60Mhz */ break; case 0x06d4423: presentMclk[iBoard] = 65000000L; /* 65Mhz */ break; case 0x06ea410: presentMclk[iBoard] = 70000000L; /* 70Mhz */ break; case 0x06ed013: presentMclk[iBoard] = 75000000L; /* 75Mhz */ break; case 0x06f7020: presentMclk[iBoard] = 80000000L; /* 80Mhz */ break; case 0x071701e: presentMclk[iBoard] = 85000000L; /* 85Mhz */ break; case 0x074fc13: presentMclk[iBoard] = 90000000L; /* 90Mhz */ break; default: ValClock = 0x065AC3D; presentMclk[iBoard] = 50000000L; /* 50Mhz */ } if(InfoDac == Info_Dac_TVP3026) { setTVP3026Freq(pMgaBaseAddr, presentMclk[iBoard] / 1000L, 3, 0); } else { /*** Program MCLOCK ***/ mgaReadBYTE(*(pMgaBaseAddr+TITAN_OFFSET+TITAN_MISC_OUT_R), TmpByte); programme_reg_icd ( pMgaBaseAddr, 3, ValClock ); mgaWriteBYTE(*(pMgaBaseAddr+TITAN_OFFSET+TITAN_MISC_ISTAT0), TmpByte); delay_us(10000); } return(mtxOK); }