?? hal.c
字號:
//=============================================================================
// HAL.C
// (Tabs set to every 4 spaces)
//---------------------------------------------------------------------------
// The routines in this file comprise the core of the S1D13700 miniHAL.
//---------------------------------------------------------------------------
//
// ㏒EIKO EPSON CORPORATION 2003-2005. All rights reserved.
//
//=============================================================================
#if defined INLINE_FUNCTIONS
#define INLINE inline
#else
#define INLINE
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined(_WIN32)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
static HANDLE ghHalMutex; // Process synchronization mutex handle
#endif
#include "hal.h"
#include "HAL_platform.h"
#include "HAL_private.h"
#include "hal_indirect.h"
#include "hal_config.c"
#include "halmutex.h"
#include "libmutex.h"
#ifdef _WIN32
#pragma warning( disable : 4100 ) // Disable "unreferenced formal parameter" warning.
#endif
//===========================================================================
// PUBLIC GLOBAL VARIABLES
//===========================================================================
char gszHALRevision[] = "$Revision: 10 $";
int gnHalErrCode;
//===========================================================================
// PRIVATE (STATIC) FUNCTION PROTOTYPES (local to HAL only)
//===========================================================================
static void InitRegisters( void );
static void ClearVideoMemory( void );
//===========================================================================
// Timing globals and defines
//===========================================================================
static __int64 gSysClockBase; // Value of CPU SysClock at calibration time
static __int64 gSysClockPS; // Calculated number of picoseconds per SysClock
static Boolean CalibrateSystemClock( void );
#define RDTSC(var64) \
__asm \
{ \
__asm rdtsc \
__asm mov dword ptr [var64+0],eax \
__asm mov dword ptr [var64+4],edx \
} ((void)0)
//===========================================================================
// PRIVATE GLOBAL VARIABLES (local to HAL only)
//===========================================================================
static DATA_STRUCT gHD = // Global HAL private data storage
{
HAL_MUTEX_REVISION,
LIB_MUTEX_REVISION,
"Copyright (c) Seiko Epson Corporation 2003-2005.\nAll rights reserved.\n"
// Remaining members are default initialized to zero.
};
// CRITICAL: The messages in this array MUST correspond to the error codes contained in the HAL.H enumeration.
static const char * const gapszErrMsg[ERR_FAILED + 1] =
{
"There was no error detected", // ERR_NONE
"Unable to find/load the S1D13xxx driver", // ERR_PCI_DRIVER_NOT_FOUND
"Unable to locate an S1D13xxx controller", // ERR_PCI_ADAPTER_NOT_FOUND
"This program has not been configured", // ERR_NOT_CONFIGURED
"Config CRC does not match configuration", // ERR_BAD_CFG_DATA
"I2C bus/device initialization failure", // ERR_BAD_I2C_INIT
"The controller has not been acquired", // ERR_NOT_ACQUIRED
"IRQ interrupt handler failure", // ERR_IRQ_FAILURE
"The CNF1 pin is low (all GPIOs are outputs)", // ERR_BAD_CNF1_SETTING
"An unspecified error occured" // ERR_FAILED
};
const DATA_STRUCT* const gpHalData = &gHD;
/*****************************************************************************/
/* FUNCTIONS exported in hal.h */
/*****************************************************************************/
//=============================================================================
// Start Up
//=============================================================================
//---------------------------------------------------------------------------
// FUNCTION: halAcquireController()
//
// DESCRIPTION:
// This is the discovery portion of the the start-up sequence.
// On the Intel platform, halAcquireController() initiates the link
// between the application and the hardware by attempting to load
// S1D13xxx.VxD. If the driver is loaded successfully then a call
// is made to the VxD to determine the presence and the address
// of the S1D13700. On all other platforms, this routine takes
// the register and display memory addresses provided by 13700CFG.
//
// This routine MUST be called before any other call to the HAL is made!
// (i.e. halInitController)
//
// Applications can call this routine only to obtain pointers to the
// registers and display memory and from there take over all access
// to the S1D13700.
//
// PARAMETERS:
// pMem - Pointer to receive the address of the first byte of display
// memory.
// pReg - Pointer to receive the address of the first byte of register
// space.
//
// RETURNS:
// TRUE if the routine is able to locate an S1D13700.
// *pMem will be the address of the first byte of display memory.
// *pReg will be the address of the first 13700 control register.
// FALSE if an S1D13700 is not located.
// If additional error information is required call
// halGetLastError().
//
// MODIFIES:
// This routine does not modify any register contents.
//---------------------------------------------------------------------------
Boolean halAcquireController( UInt32 * pMem, UInt32 * pReg )
{
static Boolean fFirstTime = FALSE;
gHD.nErrorCode = ERR_NONE;
// Init, one time, default state of debug register writes flag.
if( !fFirstTime )
{
fFirstTime = TRUE;
#ifdef _DEBUG
gHD.fDebugHalDelay = gHD.fDebugRegWrites = !!(HalInfo.dwFlags & fDEBUG_REG_WRITES);
#else
gHD.fDebugHalDelay = gHD.fDebugRegWrites = FALSE;
#endif
}
if ( HalInfo.dwFlags & fPCCARD_INTERFACE )
{
// force to PCI addressing
gHD.BaseAddress = 0;
HalInfo.dwRegisterOffset = 0;
}
// Use the configured base address to retrieve the virtual address, if any. On
// non-Windows platforms, the base address will be copied to the virtual address.
if( gHD.BaseAddress == 0 ) // Only do this once, so we are re-entrant.
{
gHD.nErrorCode = halpMapPhysicalToVirtual( HalInfo.dwBaseAddress, &gHD.BaseAddress, &gHD.BlockSize );
if( gHD.nErrorCode != ERR_NONE )
{
gHD.BaseAddress = 0;
return FALSE;
}
if ( HalInfo.dwFlags & fPCCARD_INTERFACE )
{
gHD.MemoryAddress = gHD.BaseAddress;
gHD.RegisterAddress = gHD.BaseAddress + 0x8000UL * 2; //0x8000 is the offset of reg base addr from video mem bas eaddr
}
else
{
gHD.RegisterAddress = gHD.BaseAddress + HalInfo.dwRegisterOffset;
// If the configured register and memory offsets are the same, assume we are
// using the PCI evaluation board, and default the memory offset accordingly.
gHD.MemoryAddress = gHD.BaseAddress + HAL_PCI_VRAM_OFFSET;
}
}
#ifndef HAL_SIMULATE
if( (HalInfo.dwFlags & fINDIRECT_INTERFACE) )
halpInitIndirectInterface( gHD.MemoryAddress );
#else
HalInfo.dwFlags &= ~fINDIRECT_INTERFACE; // In simulate mode, don't simulate any indirect interface!
#endif
if( pReg ) *pReg = gHD.RegisterAddress;
if( pMem ) *pMem = gHD.MemoryAddress;
//
return TRUE;
}
//---------------------------------------------------------------------------
// FUNCTION: halInitController()
//
// DESCRIPTION:
// This routine performs the initialization portion of the startup
// sequence.
//
// Initialization consists of several steps:
// - Programming the ICD2061A clock generator
// - Setting the contol registers the state defined by CFG.
// - Setting the LUT to its default value.
// - Clearing video memory
//
// Parameters passed in dwFlags can cause any or all of these steps to
// be bypassed. This allows for run-time operational changes.
//
// PARAMETERS:
// Flags - contains initialization specific information.
//
// RETURNS:
// TRUE if the initialization was successful.
// FALSE if the HAL was unable to initialize the S1D13700
//
// If additional error information is required call halGetLastError()
//
// MODIFIES:
// Nearly every register and all display memory can or will be affected.
//---------------------------------------------------------------------------
Boolean halInitController( UInt32 Flags )
{
gHD.nErrorCode = ERR_NONE;
// If the program has not been CFGed then we CANNOT init the controller.
// Set and error code and return FALSE.
// If the program has not been CFGed then we CANNOT init the controller.
// Set and error code and return FALSE.
#ifndef HAL_SIMULATE
if ( HalInfo.wHalCRC == 0x0000 )
{
gHD.nErrorCode = ERR_NOT_CONFIGURED;
return FALSE;
}
#if 0
When registers' value are changed, the CRC of HalInfo will changed and result in CRC incorrect.
gHD.nErrorCode is not checked, instead gnHalErrorCode is checked. Should gHD.nErrorCode be gnHalErrorCode ?
remove the following code for above reason.
// CRC is not zero so we have been configured. Check that the CRC
// and the data match.
if ( !(Flags & fDONT_CHECK_CRC) && HalInfo.wHalCRC != CalculateHalInfoCRC(&HalInfo) )
{
gHD.nErrorCode = ERR_BAD_CFG_DATA;
return FALSE;
}
#endif
#endif
// Fail if halAcquireController() was not called, or if it failed.
if ( gHD.BaseAddress == 0 )
{
gHD.nErrorCode = ERR_NOT_ACQUIRED;
return FALSE;
}
gHD.fDebugHalDelay = FALSE; // Don't debug delays during init, as they are special-cased!
DEBUGMSG( TRUE, (" List of HAL Initialization Events:\n") );
// Init the registers - unless the caller has requested us not to
if ( !(Flags & fDONT_INIT_REGS) )
{
InitRegisters();
DEBUGMSG( TRUE, (" - Registers initialized as per configured settings.\n") );
}
else
DEBUGMSG( TRUE, (" - Registers NOT initialized!\n") );
// Clear video memory - unless the caller has requested us not to
if ( !(Flags & fDONT_CLEAR_MEM) )
{
ClearVideoMemory();
DEBUGMSG( TRUE, (" - All video memory cleared to 00h.\n") );
}
else
DEBUGMSG( TRUE, (" - Video memory NOT cleared!\n") );
gHD.fDebugHalDelay = gHD.fDebugRegWrites;
return ( gHD.nErrorCode == ERR_NONE );
}
//===========================================================================
// Memory Access
//===========================================================================
// *** NOTE ***
//
// The memory access routines do not perform any error checking. This means:
// 1) NEVER call these routines if halAcquireController() did not succeed.
// 2) Memory boundaries are not checked. It is possible to request a read
// or write outside of display memory.
//-----------------------------------------------------------------------------
// COMMON FUNCTION: halReadDisplay8()
// COMMON FUNCTION: halReadDisplay16()
// COMMON FUNCTION: halReadDisplay32()
//-----------------------------------------------------------------------------
UInt8 halReadDisplay8( UInt32 Offset )
{
if ( HalInfo.dwFlags & fPCCARD_INTERFACE )
{
if( HalInfo.dwFlags & fINDIRECT_INTERFACE )
return halpIndReadDisplay8( (UInt16)(Offset*2) );
else
return *(pvUInt8)(gHD.MemoryAddress + (Offset*2));
}
else
{
if( HalInfo.dwFlags & fINDIRECT_INTERFACE )
return halpIndReadDisplay8( (UInt16)Offset );
else
return *(pvUInt8)(gHD.MemoryAddress + Offset);
}
}
UInt16 halReadDisplay16( UInt32 Offset )
{
if ( HalInfo.dwFlags & fPCCARD_INTERFACE )
{
if( HalInfo.dwFlags & fINDIRECT_INTERFACE )
return halpIndReadDisplay16( (UInt16)(Offset*2) );
else
{
UInt16 wRetVal;
wRetVal = *(pvUInt8)(gHD.MemoryAddress + Offset*2);
wRetVal |= (*(pvUInt8)(gHD.MemoryAddress + (Offset + 1)*2))<<8;
return wRetVal;
}
}
else
{
if( HalInfo.dwFlags & fINDIRECT_INTERFACE )
return halpIndReadDisplay16( (UInt16)Offset );
else
{
UInt16 wRetVal;
wRetVal = *(pvUInt8)(gHD.MemoryAddress + Offset);
wRetVal |= (*(pvUInt8)(gHD.MemoryAddress + Offset + 1))<<8;
return wRetVal;
}
}
}
UInt32 halReadDisplay32( UInt32 Offset )
{
if ( HalInfo.dwFlags & fPCCARD_INTERFACE )
{
if( HalInfo.dwFlags & fINDIRECT_INTERFACE )
return halpIndReadDisplay32( (UInt16)(Offset*2) );
else
{
UInt32 dwRetVal;
dwRetVal = *(pvUInt8)(gHD.MemoryAddress + Offset*2);
dwRetVal |= (*(pvUInt8)(gHD.MemoryAddress + (Offset + 1)*2))<< 8;
dwRetVal |= (*(pvUInt8)(gHD.MemoryAddress + (Offset + 1)*2))<<16;
dwRetVal |= (*(pvUInt8)(gHD.MemoryAddress + (Offset + 1)*2))<<24;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -