📄 hal_xlib.c
字号:
/*-------------------------------------------------------------------------
//
// File: hal_xlib.c
//
// Copyright (c) 1997, 1998, 2002 Epson Research and Development, Inc.
// All Rights Reserved.
//
//-----------------------------------------------------------------------*/
#ifdef INTEL
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#define WIN32_LEAN_AND_MEAN
#define NOGDI
#include <windows.h>
#pragma warning( push, 3 ) // Set warning level 3 for braindead winioctl.h!
#include <winioctl.h>
#pragma warning( pop ) // Restore warning level to build default.
#include "ioctl.h"
#endif
#include "hal.h"
#include "assert.h"
#include "nonsefns.h"
/*-----------------------------------------------------------------------*/
static const char Revision[] = "HAL_XLIB.C=$Revision: 4 $";
/*-----------------------------------------------------------------------*/
volatile DWORD RegLogicalAddr[MAX_DEVICE];
volatile DWORD DispLogicalAddr[MAX_DEVICE];
//volatile DWORD SuspendLogicalAddr = 0;
HANDLE ghDriver;
static DWORD gulLinearAddress;
/*-------------------------------------------------------------------------
//
// InitPlat()
//
//-----------------------------------------------------------------------*/
int InitPlat(void)
{
int i;
for (i = 0; i < MAX_DEVICE; ++i)
RegLogicalAddr[i] = 0;
for (i = 0; i < MAX_DEVICE; ++i)
DispLogicalAddr[i] = 0;
// SuspendLogicalAddr = 0;
return ERR_OK;
}
/*-------------------------------------------------------------------------
//
// seGetLinearDispAddr()
//
//-----------------------------------------------------------------------*/
int seGetLinearDispAddr(int seReserved1, DWORD *pDispLogicalAddr)
{
ASSERT( 0 == seReserved1 );
*pDispLogicalAddr = DispLogicalAddr[seReserved1];
return ERR_OK;
}
/*-------------------------------------------------------------------------
//
// InitLinear()
//
// WARNING: This function is only to be called by seRegisterDevice()
//
//-----------------------------------------------------------------------*/
int InitLinear(int seReserved1)
{
unsigned long errcode;
#ifdef INTEL
DWORD dwRegAddr, dwMemAddr;
DWORD ulLinearAddr;
#endif
extern LPHAL_STRUCT HalInfoArray[MAX_DEVICE];
ASSERT( 0 == seReserved1 );
#ifdef INTEL
/*
* The display buffer is allocated 2M, the registers allocated 1M,
* and the hardware suspend allocated the 1M immediately after the
* register block.
*/
dwRegAddr = HalInfoArray[seReserved1]->dwRegAddr;
dwMemAddr = HalInfoArray[seReserved1]->dwDispMemAddr;
errcode = halpGetLinearAddress(dwRegAddr, &ulLinearAddr);
if ((0 == dwMemAddr) && (0 == dwRegAddr))
{
// DispLogicalAddr[seReserved1] = ulLinearAddr;
// RegLogicalAddr[seReserved1] = DispLogicalAddr[seReserved1] + 0x200000;
RegLogicalAddr[seReserved1] = ulLinearAddr;
DispLogicalAddr[seReserved1] = RegLogicalAddr[seReserved1] + 0x200000;
}
else if (dwMemAddr < dwRegAddr)
{
DispLogicalAddr[seReserved1] = ulLinearAddr;
RegLogicalAddr[seReserved1] = DispLogicalAddr[seReserved1] + dwRegAddr - dwMemAddr;
}
else
{
RegLogicalAddr[seReserved1] = ulLinearAddr;
DispLogicalAddr[seReserved1] = RegLogicalAddr[seReserved1] + dwMemAddr - dwRegAddr;
}
if (ERR_NONE != errcode)
return ERR_FAILED;
HalInfoArray[seReserved1]->dwRegAddr = RegLogicalAddr[seReserved1];
HalInfoArray[seReserved1]->dwDispMemAddr = DispLogicalAddr[seReserved1];
/*
* Suspend function is memory mapped to 1 Mbyte segment above registers
*/
// SuspendLogicalAddr = RegLogicalAddr[seReserved1] + 0x100000;
#else
/*
* NON-INTEL SYSTEMS
*/
RegLogicalAddr[seReserved1] = HalInfoArray[seReserved1]->dwRegAddr;
DispLogicalAddr[seReserved1] = HalInfoArray[seReserved1]->dwDispMemAddr;
/*
* Suspend function not used in non Intel systems
*/
// SuspendLogicalAddr = DispLogicalAddr[seReserved1];
#endif
return ERR_OK;
}
/*-------------------------------------------------------------------------
//
// ExitLinear()
//
//-----------------------------------------------------------------------*/
int ExitLinear(int seReserved1)
{
ASSERT( 0 == seReserved1 );
/*
* Nothing to do here.
*/
/*
** Prevent compiler warning that seReserved1 is not used.
*/
seReserved1;
return ERR_OK;
}
int halpGetLinearAddress( DWORD ulPhysAddr, DWORD * 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.
ghDriver = 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
ghDriver = 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 (ghDriver == INVALID_HANDLE_VALUE)
{
ghDriver = 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(ghDriver, 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(ghDriver, 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()
//---------------------------------------------------------------------------
int halpFreeLinearAddress( void )
{
int rc = ERR_NONE;
DWORD cbReturned;
// Only free up these resources, if they are currently allocated and in use.
if (ghDriver)
{
// 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(ghDriver, 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 driver as closed and the allocated memory freed.
CloseHandle(ghDriver);
ghDriver = NULL;
gulLinearAddress = 0;
}
return rc;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -