//////////////////////////////////////////////////////////////////////
// File - SCREEN_LIB.C
//
// Library for accessing the SCREEN card.
// Code was generated by Driver Wizard.
// It accesses the hardware via WinDriver functions.
//
// Copyrights (c) Jungo Ltd. 2000
//////////////////////////////////////////////////////////////////////
#include "screen_lib.h"
#include <stdio.h>
// This string is set to an error message, if one occurs
CHAR SCREEN_ErrorString[1024];
// Internal data structures
typedef struct
{
DWORD index;
DWORD dwMask;
BOOL fIsMemory;
BOOL fActive;
} SCREEN_ADDR_DESC;
typedef struct SCREEN_STRUCT
{
HANDLE hWD;
BOOL fUseInt;
WD_PCI_SLOT pciSlot;
SCREEN_ADDR_DESC addrDesc[SCREEN_ITEMS];
WD_CARD_REGISTER cardReg;
} SCREEN_STRUCT;
// Internal function used by SCREEN_Open()
BOOL SCREEN_DetectCardElements(SCREEN_HANDLE hSCREEN);
DWORD SCREEN_CountCards (DWORD dwVendorID, DWORD dwDeviceID)
{
WD_VERSION ver;
WD_PCI_SCAN_CARDS pciScan;
HANDLE hWD;
SCREEN_ErrorString[0] = '\0';
hWD = WD_Open();
// Check if handle valid & version OK
if (hWD==INVALID_HANDLE_VALUE)
{
sprintf( SCREEN_ErrorString, "Failed opening WinDriver device\n");
return 0;
}
BZERO(ver);
WD_Version(hWD,&ver);
if (ver.dwVer<WD_VER)
{
sprintf( SCREEN_ErrorString, "Incorrect WinDriver version\n");
WD_Close (hWD);
return 0;
}
BZERO(pciScan);
pciScan.searchId.dwVendorId = dwVendorID;
pciScan.searchId.dwDeviceId = dwDeviceID;
WD_PciScanCards (hWD, &pciScan);
WD_Close (hWD);
if (pciScan.dwCards==0)
sprintf( SCREEN_ErrorString, "no cards found\n");
return pciScan.dwCards;
}
BOOL SCREEN_Open (SCREEN_HANDLE *phSCREEN, DWORD dwVendorID, DWORD dwDeviceID, DWORD nCardNum, DWORD dwOptions)
{
SCREEN_HANDLE hSCREEN = (SCREEN_HANDLE) malloc (sizeof (SCREEN_STRUCT));
WD_VERSION ver;
WD_PCI_SCAN_CARDS pciScan;
WD_PCI_CARD_INFO pciCardInfo;
*phSCREEN = NULL;
SCREEN_ErrorString[0] = '\0';
BZERO(*hSCREEN);
hSCREEN->cardReg.hCard = 0;
hSCREEN->hWD = WD_Open();
// Check if handle valid & version OK
if (hSCREEN->hWD==INVALID_HANDLE_VALUE)
{
sprintf( SCREEN_ErrorString, "Failed opening WinDriver device\n");
goto Exit;
}
BZERO(ver);
WD_Version(hSCREEN->hWD,&ver);
if (ver.dwVer<WD_VER)
{
sprintf( SCREEN_ErrorString, "Incorrect WinDriver version\n");
goto Exit;
}
BZERO(pciScan);
pciScan.searchId.dwVendorId = dwVendorID;
pciScan.searchId.dwDeviceId = dwDeviceID;
WD_PciScanCards (hSCREEN->hWD, &pciScan);
if (pciScan.dwCards==0) // Found at least one card
{
sprintf( SCREEN_ErrorString, "Could not find PCI card\n");
goto Exit;
}
if (pciScan.dwCards<=nCardNum)
{
sprintf( SCREEN_ErrorString, "Card out of range of available cards\n");
goto Exit;
}
BZERO(pciCardInfo);
pciCardInfo.pciSlot = pciScan.cardSlot[nCardNum];
WD_PciGetCardInfo (hSCREEN->hWD, &pciCardInfo);
hSCREEN->pciSlot = pciCardInfo.pciSlot;
hSCREEN->cardReg.Card = pciCardInfo.Card;
hSCREEN->fUseInt = (dwOptions & SCREEN_OPEN_USE_INT) ? TRUE : FALSE;
if (!hSCREEN->fUseInt)
{
DWORD i;
// Remove interrupt item if not needed
for (i=0; i<hSCREEN->cardReg.Card.dwItems; i++)
{
WD_ITEMS *pItem = &hSCREEN->cardReg.Card.Item[i];
if (pItem->item==ITEM_INTERRUPT)
pItem->item = ITEM_NONE;
}
}
//else
{
DWORD i;
// Make interrupt resource sharable
for (i=0; i<hSCREEN->cardReg.Card.dwItems; i++)
{
WD_ITEMS *pItem = &hSCREEN->cardReg.Card.Item[i];
//if (pItem->item==ITEM_INTERRUPT)
pItem->fNotSharable = FALSE;
}
}
hSCREEN->cardReg.fCheckLockOnly = FALSE;
WD_CardRegister (hSCREEN->hWD, &hSCREEN->cardReg);
if (hSCREEN->cardReg.hCard==0)
{
sprintf ( SCREEN_ErrorString, "Failed locking device.\n");
goto Exit;
}
if (!SCREEN_DetectCardElements(hSCREEN))
{
sprintf ( SCREEN_ErrorString, "Card does not have all items expected for SCREEN\n");
goto Exit;
}
// Open finished OK
*phSCREEN = hSCREEN;
return TRUE;
Exit:
// Error during Open
if (hSCREEN->cardReg.hCard)
WD_CardUnregister(hSCREEN->hWD, &hSCREEN->cardReg);
if (hSCREEN->hWD!=INVALID_HANDLE_VALUE)
WD_Close(hSCREEN->hWD);
free (hSCREEN);
return FALSE;
}
void SCREEN_Close(SCREEN_HANDLE hSCREEN)
{
// Unregister card
if (hSCREEN->cardReg.hCard)
WD_CardUnregister(hSCREEN->hWD, &hSCREEN->cardReg);
// Close WinDriver
WD_Close(hSCREEN->hWD);
free (hSCREEN);
}
DWORD SCREEN_ReadPCIReg(SCREEN_HANDLE hSCREEN, DWORD dwReg)
{
WD_PCI_CONFIG_DUMP pciCnf;
DWORD dwVal;
BZERO(pciCnf);
pciCnf.pciSlot = hSCREEN->pciSlot;
pciCnf.pBuffer = &dwVal;
pciCnf.dwOffset = dwReg;
pciCnf.dwBytes = 4;
pciCnf.fIsRead = TRUE;
WD_PciConfigDump(hSCREEN->hWD,&pciCnf);
return dwVal;
}
BOOL SCREEN_DetectCardElements(SCREEN_HANDLE hSCREEN)
{
DWORD i;
DWORD ad_sp;
BZERO(hSCREEN->addrDesc);
for (i=0; i<hSCREEN->cardReg.Card.dwItems; i++)
{
WD_ITEMS *pItem = &hSCREEN->cardReg.Card.Item[i];
switch (pItem->item)
{
case ITEM_MEMORY:
case ITEM_IO:
{
DWORD dwBytes;
DWORD dwPhysAddr;
BOOL fIsMemory;
if (pItem->item==ITEM_MEMORY)
{
dwBytes = pItem->I.Mem.dwBytes;
dwPhysAddr = pItem->I.Mem.dwPhysicalAddr;
fIsMemory = TRUE;
}
else
{
dwBytes = pItem->I.IO.dwBytes;
dwPhysAddr = pItem->I.IO.dwAddr;
fIsMemory = FALSE;
}
for (ad_sp=0; ad_sp<SCREEN_ITEMS; ad_sp++)
{
DWORD dwPCIAddr;
DWORD dwPCIReg;
if (SCREEN_IsAddrSpaceActive(hSCREEN, (SCREEN_ADDR) ad_sp)) continue;
if (ad_sp<SCREEN_AD_EPROM) dwPCIReg = PCI_BAR0 + 4*ad_sp;
else dwPCIReg = PCI_ERBAR;
dwPCIAddr = SCREEN_ReadPCIReg(hSCREEN, dwPCIReg);
if (dwPCIAddr & 1)
{
if (fIsMemory) continue;
dwPCIAddr &= ~0x3;
}
else
{
if (!fIsMemory) continue;
dwPCIAddr &= ~0xf;
}
if (dwPCIAddr==dwPhysAddr)
break;
}
if (ad_sp<SCREEN_ITEMS)
{
DWORD j;
hSCREEN->addrDesc[ad_sp].fActive = TRUE;
hSCREEN->addrDesc[ad_sp].index = i;
hSCREEN->addrDesc[ad_sp].fIsMemory = fIsMemory;
hSCREEN->addrDesc[ad_sp].dwMask = 0;
for (j=1; j<dwBytes && j!=0x80000000; j *= 2)
{
hSCREEN->addrDesc[ad_sp].dwMask =
(hSCREEN->addrDesc[ad_sp].dwMask << 1) | 1;
}
}
}
break;
}
}
// Check that all the items needed were found
// Check that at least one memory space was found
for (i = 0; i<SCREEN_ITEMS; i++)
if (SCREEN_IsAddrSpaceActive(hSCREEN, (SCREEN_ADDR) i)) break;
if (i==SCREEN_ITEMS) return FALSE;
return TRUE;
}
BOOL SCREEN_IsAddrSpaceActive(SCREEN_HANDLE hSCREEN, SCREEN_ADDR addrSpace)
{
return hSCREEN->addrDesc[addrSpace].fActive;
}
// General read/write function
void SCREEN_ReadWriteBlock(SCREEN_HANDLE hSCREEN, SCREEN_ADDR addrSpace, DWORD dwOffset, BOOL fRead, PVOID buf, DWORD dwBytes, SCREEN_MODE mode)
{
WD_TRANSFER trans;
BOOL fMem = hSCREEN->addrDesc[addrSpace].fIsMemory;
// Safty check: is the address range active
if (!SCREEN_IsAddrSpaceActive(hSCREEN, addrSpace)) return;
BZERO(trans);
if (fRead)
{
if (mode==SCREEN_MODE_BYTE) trans.cmdTrans = fMem ? RM_SBYTE : RP_SBYTE;
else if (mode==SCREEN_MODE_WORD) trans.cmdTrans = fMem ? RM_SWORD : RP_SWORD;
else if (mode==SCREEN_MODE_DWORD) trans.cmdTrans = fMem ? RM_SDWORD : RP_SDWORD;
}
else
{
if (mode==SCREEN_MODE_BYTE) trans.cmdTrans = fMem ? WM_SBYTE : WP_SBYTE;
else if (mode==SCREEN_MODE_WORD) trans.cmdTrans = fMem ? WM_SWORD : WP_SWORD;
else if (mode==SCREEN_MODE_DWORD) trans.cmdTrans = fMem ? WM_SDWORD : WP_SDWORD;
}
if (fMem)
trans.dwPort = hSCREEN->cardReg.Card.Item[hSCREEN->addrDesc[addrSpace].index].I.Mem.dwTransAddr;
else trans.dwPort = hSCREEN->cardReg.Card.Item[hSCREEN->addrDesc[addrSpace].index].I.IO.dwAddr;
trans.dwPort += dwOffset;
trans.fAutoinc = TRUE;
trans.dwBytes = dwBytes;
trans.dwOptions = 0;
trans.Data.pBuffer = buf;
WD_Transfer (hSCREEN->hWD, &trans);
}
void SCREEN_WriteDword (SCREEN_HANDLE hSCREEN, SCREEN_ADDR addrSpace, DWORD dwOffset, DWORD data)
{
if (hSCREEN->addrDesc[addrSpace].fIsMemory)
{
PDWORD pData = (PDWORD) (hSCREEN->cardReg.Card.Item[hSCREEN->addrDesc[addrSpace].index].I.Mem.dwUserDirectAddr + dwOffset);
*pData = data; // Write to the memory mapped range directly
}
else SCREEN_ReadWriteBlock( hSCREEN, addrSpace, dwOffset, FALSE, &data, sizeof (DWORD), SCREEN_MODE_DWORD);
}
BOOL PCI_Get_WD_handle(HANDLE *phWD)
{
WD_VERSION ver;
*phWD = WD_Open();
// Check whether handle is valid and version OK
if (*phWD==INVALID_HANDLE_VALUE)
{
printf("Failed opening WinDriver device\n");
return FALSE;
}
BZERO(ver);
WD_Version(*phWD,&ver);
if (ver.dwVer<WD_VER)
{
printf("Incorrect WinDriver version\n");
WD_Close (*phWD);
*phWD = INVALID_HANDLE_VALUE;
return FALSE;
}
return TRUE;
}
SCREEN_HANDLE SCREEN_LocateAndOpenBoard (DWORD dwVendorID, DWORD dwDeviceID, BOOL fUseInt, PVOID *pScreen)
{
DWORD cards, my_card;
SCREEN_HANDLE hSCREEN = NULL;
char line[256];
cards = SCREEN_CountCards (dwVendorID, dwDeviceID);
if (cards==0)
{
printf("%s", SCREEN_ErrorString);
return NULL;
}
else if (cards==1)
my_card = 1;
else
{
DWORD i;
printf("Found %d matching PCI cards\n", cards);
printf("Select card (1-%d): ", cards);
i = 0;
gets(line);
sscanf (line, "%d",&i);
if (i>=1 && i <=cards) my_card = i;
else
{
printf ("Choice out of range\n");
return NULL;
}
}
if (!SCREEN_Open (&hSCREEN, dwVendorID, dwDeviceID, my_card - 1, fUseInt ? SCREEN_OPEN_USE_INT : 0 ))
return NULL;
*pScreen = (PVOID) hSCREEN->cardReg.Card.Item[hSCREEN->addrDesc[0].index].I.Mem.dwUserDirectAddr;
return hSCREEN;
}
BOOL DrawPicture(PVOID pBuffer, FRAME_INFO frameInfo, BOOL first_time, BOOL last_time)
{
int i;
BYTE *pBGR_Buffer = (BYTE *)pBuffer;
static SCREEN_HANDLE hSCREEN = NULL;
static PVOID pScreen = 0;
PBYTE pb;
if (first_time)
{
if (SCREEN_DEFAULT_VENDOR_ID)
hSCREEN = SCREEN_LocateAndOpenBoard(SCREEN_DEFAULT_VENDOR_ID, SCREEN_DEFAULT_DEVICE_ID, FALSE, &pScreen);
else
return (FALSE);
if (!hSCREEN)
return (FALSE);
}
if (!pScreen)
return FALSE;
pb = (PBYTE) pScreen;
for (i=0; i<frameInfo.frameRowNum; i++)
memcpy(pb + STRID*3*i, pBGR_Buffer + frameInfo.frameColNum*3*i, frameInfo.frameColNum*3);
if (last_time)
{
if (hSCREEN)
SCREEN_Close(hSCREEN);
pScreen = NULL;
hSCREEN = NULL;
}
}