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

3357 lines
103 KiB
C

/*/****************************************************************************
* 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 <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <dos.h>
#include <time.h>
#endif /* #ifdef WINDOWS_NT */
#ifdef OS2
#include <os2.h>
#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<NbBoard; Board++)
{
#if ((!defined (WINDOWS_NT)) || (USE_DDC_CODE))
/*********** DDC COMPAQ CODE ****************/
if (NbBoard == 1)
if (ReportDDCcapabilities())
SupportDDC = (byte)ReadEdid();
/*********** DDC COMPAQ CODE ****************/
#endif
#ifdef PRINT_DEBUG
{
debug_printf("BOARD No %d\n", Board);
}
#endif
if (! mtxSelectHw(&Hw[Board]))
{
#ifdef PRINT_DEBUG
closeDebugfFile("mtxSelectHw Fail");
#endif
return(mtxFAIL);
}
mtxMapVLBSpace();
pMgaInfo = selectMgaInfoBoard();
if (! pMgaInfo)
{
#ifdef PRINT_DEBUG
closeDebugfFile("selectMgaInfoBoard Fail");
#endif
return(mtxFAIL);
}
/* Initialize according to Vgaen switch (strapping conf.) */
mgaReadDWORD(*(pMgaBaseAddr+TITAN_OFFSET+TITAN_CONFIG),TmpDword);
if (TmpDword&TITAN_VGAEN_M)
Hw[Board].VGAEnable = 1;
else
{
Hw[Board].VGAEnable = 0;
if (! CheckHwAllDone)
{
/*----- SoftReset (need for PCI IMPRSESSION+ with high freq --*/
mgaWriteDWORD(*(pMgaBaseAddr + TITAN_OFFSET + TITAN_RST), TITAN_SOFTRESET_SET);
delay_us(2);
mgaWriteDWORD(*(pMgaBaseAddr + TITAN_OFFSET + TITAN_RST), TITAN_SOFTRESET_CLR);
delay_us(2);
}
}
#if ((!defined (WINDOWS_NT)) || (USE_DDC_CODE))
/*********** DDC COMPAQ CODE ****************/
if (SupportDDC && Hw[0].VGAEnable)
Hw[0].PortCfg = 0x01;
if (SupportDDC && (!Hw[0].VGAEnable || mgainf != DefaultVidset))
SupportDDC = FALSE;
/*********** DDC COMPAQ CODE ****************/
#endif
if (TmpDword&0x00000001)
Hw[Board].Device8_16 = 1; /* mode 16-bit */
else
Hw[Board].Device8_16 = 0; /* mode 8-bit */
#ifdef WINDOWS_NT
if ((Hw[iBoard].pHwMode != NULL) &&
(NbBoard > 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);
}