📄 hal_supt.c
字号:
//===========================================================================
// HAL_SUPT.C -
// (Tabs set to every 4 spaces)
//---------------------------------------------------------------------------
//
// Copyright (c) 2002 Epson Research and Development, Inc.
// All Rights Reserved.
//
//===========================================================================
#include "hal.h"
#include "hal_indirect.h"
#include "hal_Supt.h"
#if defined(INTEL_W32)
#include <windows.h>
#include <winioctl.h>
#include "ioctl.h"
#endif
// Define some useful pre-processor macros.
#if defined(offsetof)
#error A chipdef.cpp pre-processor macro is already in use!
#else
#define offsetof(s,m) (int)&(((s *)0)->m)
#endif
#define ABS(x) (((x) >= 0) ? (x) : -(x))
//===========================================================================
// Global Variables
//===========================================================================
extern int gnHalErrCode;
extern pvUInt32 gpHalMemAddr;
extern pvUInt32 gpHalRegAddr;
//---------------------------------------------------------------------------
#if defined(INTEL_W32)
//---------------------------------------------------------------------------
static UInt32 gulLinearAddress;
static HANDLE hDriver;
//---------------------------------------------------------------------------
// FUNCTION: halpGetLinearAddress()
//
// DESCRIPTION:
// This routine dynamically loads the VxD and requests a linear address
// for the address space of the S1D13A03 PCI eval card.
//
// PARAMETERS:
// ulPhysAddr - A DWORD value containing the memory address offset
// to the S1D13700.
// If this value is zero (NULL) then the routine will
// load the VxD and determine the linear address of
// the S1D13700.
// If set to anything other than NULL then the value
// is assumed to be a physical address and this routine
// will return the linear address reprsenting that
// physical address.
// pulLinearAddr- Pointer to a DWORD to recieve the linear address
// for representing the physical address for the
// S1D13700.
//
// RETURNS:
// ERR_NONE - No errors, the function succeeded.
// ERR_PCI_DRIVER_NOT_FOUND - S1D13xxx.VxD was not found/loaded.
// ERR_PCI_ADAPTER_NOT_FOUND - The VxD was unable to locate an S1D13xxx.
//
// If there are no errors then * LinAddr will contain the linear address
// of the start of S1D13xxx address space. If there was a problem then
// * ulLinAddr will be zero (NULL).
//
// MODIFIES:
//---------------------------------------------------------------------------
int halpGetLinearAddress( UInt32 ulPhysAddr, UInt32 * pulLinearAddr )
{
DWORD cbReturned;
int rc, retVal;
unsigned retArr[2];
// Free and release driver, if one's currently in use. This makes
// this function and halAquireController() fully rentrant so they
// can be called multiple times, if required by the application.
halpFreeLinearAddress();
// Determine the operating system we are running under and act accordingly.
if (GetVersion() < 0x80000000)
{
// Attempt to open the device NT fashion.
hDriver = CreateFile("\\\\.\\S1D13xxx", GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
}
else //Win95,98...
{
// Attempt to open the device 95/98 fashion.
// The FILE_FLAG_DELETE_ON_CLOSE flag is used so that CloseHandle()
// can be used to dynamically unload the VxD.
// The CREATE_NEW flag is not necessary
hDriver = CreateFile("\\\\.\\S1D13xxx.VXD", 0, 0, 0, CREATE_NEW,
FILE_FLAG_DELETE_ON_CLOSE, 0);
}
// If we have an invalid handle then we didn't load the VxD.
if (hDriver == INVALID_HANDLE_VALUE)
{
hDriver = NULL;
return ERR_PCI_DRIVER_NOT_FOUND;
}
//---------------------------------------------------
// From now on, the code is common for Win95 & WinNT
//---------------------------------------------------
if (ulPhysAddr == 0) // map in a PCI Board
{
char Buffer[80];
int boardnum = 0;
// Check the environment for:
// S1DBOARD=x
// where x is a number 0,1,2,3,4,...
// This is for those rare situations, where we have multiple
// PCI boards and we have "assigned" a command prompt window
// to a particular board using the environment variables.
if (GetEnvironmentVariable("SEDBOARD", Buffer, sizeof(Buffer)))
boardnum = atoi(Buffer);
rc = DeviceIoControl(hDriver, IOCTL_SED_MAP_PCI_BOARD,
&boardnum, sizeof(ULONG), retArr,
2*sizeof(ULONG), &cbReturned,NULL);
// Upon exit from DeviceIoControl():
// retArr[0] : linear address
// retArr[1] : physical address
if (rc)
{
*pulLinearAddr = retArr[0];
gulLinearAddress = retArr[0];
}
}
else // The user insists on a particular physical address
{
retArr[0] = ulPhysAddr;
retArr[1] = 4 * 1024 * 1024;
rc = DeviceIoControl(hDriver, IOCTL_SED_MAP_PHYSICAL_MEMORY,
&retArr[0], 2 * sizeof(ULONG), &retVal,
sizeof(ULONG), &cbReturned, NULL);
if (rc)
{
*pulLinearAddr = retVal;
gulLinearAddress = retVal;
}
}
if (rc)
return ERR_NONE;
return ERR_PCI_ADAPTER_NOT_FOUND;
}
//---------------------------------------------------------------------------
// FUNCTION: halpFreeLinearAddress()
//
// DESCRIPTION:
// This routine frees the memory allocated by GetLinearAddrW32().
// Failure to release the memory blocks will result in the eventual
// failure of the program to run.
//
// PARAMETERS:
//
// RETURNS:
// ERR_NONE - No errors, the function succeeded.
// ERR_PCI_ADAPTER_NOT_FOUND - The VxD was unable to locate an S1D13xxx.
//
// MODIFIES:
//---------------------------------------------------------------------------
int halpFreeLinearAddress( void )
{
int rc = ERR_NONE;
DWORD cbReturned;
// Only free up these resources, if they are currently allocated and in use.
if (hDriver)
{
// We already have a handle to the VxD and to the memory we wish to free.
// Simply call the VxD with the appropriate values to free the our memory.
if ( gulLinearAddress )
if ( !DeviceIoControl(hDriver, IOCTL_SED_UNMAP_LINEAR_MEMORY, &gulLinearAddress,
sizeof(PVOID), NULL, 0, &cbReturned, NULL) )
rc = ERR_PCI_ADAPTER_NOT_FOUND;
// Close the handle. This dynamically UNLOADs the VxD under Win9x. Also
// flag the SED driver closed and the allocated memory freed.
CloseHandle(hDriver);
hDriver = NULL;
gulLinearAddress = 0;
}
return rc;
}
#endif
static UInt32 fREF = 14318180; // 14.31818 MHz
//---------------------------------------------------------------------------
// FUNCTION: halpInitRegisters()
//
// DESCRIPTION:
// This function simply takes the register list in the HalInfo structure
// and writes it to the registers.
//
// Certain control codes (eg. REG_END_OF_TABLE) are interpreted and
// appropriate action taken.
//
// PARAMETERS: none.
//
// RETURNS: Nothing
//
// MODIFIES:
// Pretty much every LCD controller register will be written to.
//---------------------------------------------------------------------------
void halpInitRegisters( void )
{
UInt16 i;
UInt16 wReg08 = HalInfo.Regs[REG0007_SYSTEMSET_P8].Value; // Save register 8
HalInfo.Regs[REG0007_SYSTEMSET_P8].Value = 0; // Power up
halWriteReg8( (UInt16)REG0007_SYSTEMSET_P8, 0 ); // Power up
//
if( HalInfo.dwFlags&fINDIRECT_INTERFACE )
{
PICOMMAND pCurCmd, pPreCmd = NULL;
//
for( i=0; i<HAL_NUMREGS; i++ )
{
pCurCmd = gCmdTbl[i];
//
if( pPreCmd!=pCurCmd )
{
halIndirectRegCmd( pCurCmd );
pPreCmd = pCurCmd;
}
}
} else
{
for( i=0; i<HAL_NUMREGS; i++ ) halWriteReg8( i, (UInt8)HalInfo.Regs[i].Value );
}
//
HalInfo.Regs[8].Value = wReg08;
HalInfo.Regs[REG0007_SYSTEMSET_P8].Value = wReg08; // Restore register 8
halWriteReg8( (UInt16)REG0007_SYSTEMSET_P8, (UInt8)wReg08 ); // Finally restore power state that is
// intended as the register setting
return;
}
//---------------------------------------------------------------------------
// FUNCTION: halpClearVmem()
//
// DESCRIPTION:
// This routine calculates the amount of video memory present and clears
// all of it by setting the memory to zero.
//
// Any memory amounts hinted in the HAL are not used.
//
// PARAMETERS: None.
//
// RETURNS: Nothing.
//
// MODIFIES: Sets all of video memory to zero.
//---------------------------------------------------------------------------
void halpClearVmem( void )
{
pvUInt32 ptr;
UInt32 ulCount;
UInt32 cnt;
ptr = gpHalMemAddr;
ulCount = 0x8000;
if (HalInfo.dwFlags & fINDIRECT_INTERFACE)
{
//halIndirectWriteDisplayAddress(0);
for (cnt = 0; cnt < ulCount; cnt++)
*pIndirectDataWrite = (UInt8)0;
}
else
{
for (cnt = 0; cnt < ulCount; cnt++, ptr++)
*ptr = (UInt8)0;
}
}
//---------------------------------------------------------------------------
// FUNCTION: halpCalculateHalInfoCRC()
//
// DESCRIPTION:
// This routine is taken directly from 13700CFG. However, to accomodate
// differences between C and C++ there are a couple of small changes.
//
// This private method is used to calculate a 16-bit CRC for the contents
// of a HalInfo structure. The bits included in the calculation are those
// from the first byte following the wHalCRC member up to and including
// the last byte of the structure. The formula used is CRC16-CCITT, which
// is the polynomial x^16 + x^12 + x^5 + 1 (0x1021).
//
// PARAMETERS:
// HalData - Pointer to a HAL_STRUCT structure
//
// RETURNS:
// The calculated CRC value.
//---------------------------------------------------------------------------
UInt16 halpCalculateHalInfoCRC( const PHAL_STRUCT pHalData )
{
const UInt8 *pHalByte;
int i, nBytes;
UInt16 crc;
// Setup the pointer, counter, and initial CRC value.
pHalByte = (UInt8 *) &(pHalData->wHalCRC) + sizeof(HalInfo.wHalCRC);
nBytes = sizeof(HalInfo) - offsetof(HAL_STRUCT,wHalCRC) - sizeof(HalInfo.wHalCRC);
crc = 0xFFFF;
// Calculate the CRC for the HalInfo structure (from byte after wHalCRC to end).
for (i = 0; i < nBytes; i++)
{
crc = (crc << 8) | ((crc >> 8) ^ pHalByte[i]);
crc ^= (crc & 0x00FF) >> 4;
crc ^= (crc << 12) ^ ((crc & 0x00FF) << 5);
}
// Return the calculated CRC.
return crc;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -