📄 hal_init.c
字号:
/*
**===========================================================================
** HAL_INIT.C
**---------------------------------------------------------------------------
** Copyright (c) 1997, 2001 Epson Research and Development, Inc.
** All Rights Reserved.
**===========================================================================
*/
#if defined(INTEL_W32) || defined(INTEL_DOS)
#include <stdio.h>
#endif
#include <string.h>
#include "hal.h"
#include "assert.h"
#include "nonsefns.h"
/*-------------------------------------------------------------------------*/
static const char Revision[] = "HAL_INIT.C=$Revision: 26 $";
/*-------------------------------------------------------------------------*/
extern BYTE LUT1[2*3];
extern BYTE LUT2_Color[4*3];
extern BYTE LUT2_Mono[4*3];
extern BYTE LUT4_Color[16*3];
extern BYTE LUT8_Color[256*3];
/*-------------------------------------------------------------------------*/
DWORD _MemorySize;
BOOL _EndianReverseBytes = FALSE;
/*-------------------------------------------------------------------------*/
/*
** Find the register value in _HalInfo[]
*/
int _FindReg(unsigned index, unsigned *pValue, int *iArray)
{
int i;
defReg *pRegs;
int GotReg;
GotReg = FALSE;
*pValue = 0;
*iArray = 0;
pRegs = &(_HalInfo->Regs[0]);
/*
** Get the last entry in Reg table referring to REG[index]
*/
for (i = 0; (i < MAX_REG) && (pRegs->index != FINISHED_REG_CFG); ++i, ++pRegs)
{
if (pRegs->index == index)
{
*pValue = pRegs->val;
*iArray = i;
GotReg = TRUE;
}
}
if (GotReg)
return ERR_OK;
else
return ERR_FAILED;
}
/*-------------------------------------------------------------------------*/
/*
** The following registration function will not perform any
** register I/O
*/
int _RegisterDevice(const LPHAL_STRUCT lpHalInfo)
{
int err;
_InitPlat();
// Clear surfaces
memset(&_LcdSurface, 0, sizeof(_SURFACE_STRUCT));
memset(&_CrtTvSurface, 0, sizeof(_SURFACE_STRUCT));
memset(&_LcdInkCursor, 0, sizeof(_INK_CURSOR_STRUCT));
memset(&_CrtTvInkCursor, 0, sizeof(_INK_CURSOR_STRUCT));
_LcdSurface.DisplayMode = LCD;
_CrtTvSurface.DisplayMode = CRT;
_ActiveImageSurface = &_LcdSurface;
_AutoAllocDualPanelBufferAddr = 0;
_ThreadPriorityNestCount = 0;
_EndianReverseBytes = FALSE;
_HalInfo = lpHalInfo;
err = _InitLinear();
if (err != ERR_OK)
return err;
/*
** Assume 2M bytes of memory. The user must call seInitReg()
** to ensure that _MemorySize is correct by calling _CheckMemory().
** _CheckMemory() isn't called here because if the host interface isn't
** enabled, _CheckMemory() may cause the platform to generate an error
** when registers are read.
*/
_MemorySize = 0x200000; /* 2M bytes */
_seVmemInit(_MemorySize);
seCheckEndian(&_EndianReverseBytes);
seAllocLcdSurface(0x10000); // allocate some memory just to prevent HAL from crashing
seSetLcdAsActiveSurface();
return ERR_OK;
}
/*-------------------------------------------------------------------------*/
/*
** seRegisterDevice()
**
** This function MUST be called first to set up the HAL library.
*/
int seRegisterDevice(const LPHAL_STRUCT lpHalInfo)
{
unsigned regMisc;
int id;
int err;
err = _RegisterDevice(lpHalInfo);
if (err != ERR_OK)
return err;
/*
** Enable host interface
*/
regMisc = seReadRegByte(REG_MISC);
regMisc &= ~0x80;
seWriteRegByte(REG_MISC, regMisc);
_MemorySize = seGetInstalledMemorySize();
_seVmemInit(_MemorySize);
seGetId(&id);
_AutoAllocSurface(seReadRegByte(REG_DISPLAY_MODE) & 0x07);
if (id == ID_UNKNOWN)
return ERR_UNKNOWN_DEVICE;
else
return ERR_OK;
}
/*-------------------------------------------------------------------------*/
int seHalTerminate(void)
{
#ifdef INTEL_W32
switch (_IntelUnmapLinearMemory())
{
case 0:
return ERR_OK;
case 1:
return ERR_PCI_DRIVER_NOT_FOUND;
case 2:
return ERR_PCI_BRIDGE_ADAPTER_NOT_FOUND;
default:
return ERR_FAILED;
}
#else
return ERR_OK;
#endif
}
/*-------------------------------------------------------------------------*/
DWORD seGetInstalledMemorySize(void)
{
unsigned MemConfig;
MemConfig = seReadRegByte(REG_MD_CFG_STATUS0) >> 6;
/*
** Determine amount of memory available by using lines MD7:6
*/
switch (MemConfig)
{
case 0:
case 2:
return 0x80000; /* 512K bytes */
default:
return 0x200000; /* 2M bytes */
}
}
/*-------------------------------------------------------------------------*/
/*
** This routine sets the register values for the given device.
** The reason for setting the registers separately from the
** the registration is to support programs like PLAY where
** it is undesirable to indiscriminately blow the registers.
*/
/*
** Legal values for DisplayMode:
** LCD, CRT, TV, LCD | CRT, LCD | TV
**
**
** If DisplayMode is non-zero, this value overrides that
** in the CFG register structure.
**
** Legal values for flags:
** CLEAR_MEM, DISP_BLANK
** To combine the above flags, use the logical OR operation.
** For example, (CLEAR_MEM | DISP_BLANK) clears memory and
** turns off the display FIFO.
**
** WARNING: seInitReg() can NOT call any function which
** relies on the display surface. The display surface
** is initialized AFTER all other registers are initialized.
*/
int seInitReg(unsigned DisplayMode, unsigned flags)
{
int idx, index;
defReg *pRegs;
int i;
BYTE color[3];
unsigned val;
unsigned regLcdDisplayMode, regCrtTvDisplayMode;
char *szFreq;
DWORD bits;
int iFreq;
int err;
int errClock;
int iDisplayMode;
_FindReg(REG_DISPLAY_MODE, &val, &iDisplayMode);
/*
** Write to registers.
*/
pRegs = &(_HalInfo->Regs[0]);
for (index = 0; index < MAX_REG; ++index, ++pRegs)
{
idx = pRegs->index;
val = pRegs->val;
if (idx == FINISHED_REG_CFG)
break;
if (flags & DISP_BLANK)
{
if (idx == REG_LCD_DISPLAY_MODE)
val |= 0x80; /* Set LCD Display Blank */
else if (idx == REG_CRTTV_DISPLAY_MODE)
val |= 0x80; /* CRT/TV Display Blank */
}
if ((index == iDisplayMode) && (idx == REG_DISPLAY_MODE) && (DisplayMode != 0))
val = DisplayMode;
#ifdef MCLK_SOURCE_SELECT_ADJUSTMENT
#pragma message( "Implementing code to handle MCLK Source Select bit (REG[10h] bit 0)" )
/*
** When changing REG[10h] bit 0, you must first set REG[10h] bit 4 to 1.
*/
if (idx == REG_MEM_CLOCK_CFG)
{
val = seReadRegByte(REG_MEM_CLOCK_CFG) | 0x10;
seWriteRegByte(REG_MEM_CLOCK_CFG, val); // REG[10h] bit 4 = 1
val &= ~0x01;
val |= pRegs->val & 0x01;
seWriteRegByte(REG_MEM_CLOCK_CFG, val); // REG[10h] bit 0 = desired value
val = pRegs->val; // REG[10h] bit 4 = originally configured value
}
#endif
if (idx == REG_DISPLAY_MODE)
seLcdDisplayEnable(val & 0x01); // ensure that LCD power is properly handled
seWriteRegByte(idx, val);
}
/*
** Based on the current BPP - set the LUT to default values.
*/
regLcdDisplayMode = seReadRegByte(REG_LCD_DISPLAY_MODE);
regCrtTvDisplayMode = seReadRegByte(REG_CRTTV_DISPLAY_MODE);
if (seReadRegByte(REG_PANEL_TYPE) & 0x04) /* color */
{
/*
** Initialize LCD LUT
*/
switch (regLcdDisplayMode & 0x07)
{
case 2: /* 4 bpp color */
_WriteLut(LCD, LUT4_Color, 16);
break;
case 3: /* 8 bpp color */
_WriteLut(LCD, LUT8_Color, 256);
break;
default:
break;
}
}
else switch (regLcdDisplayMode & 0x07)
{
case 2: /* 4 bpp mono */
for (i = 0; i < 16; ++i)
{
color[HAL_RED] = (BYTE) (i << 4);
color[HAL_GREEN] = (BYTE) (i << 4);
color[HAL_BLUE] = (BYTE) (i << 4);
_WriteLutEntry(LCD, i, color);
}
break;
case 3: /* 8 bpp mono */
for (i = 0; i < 256; ++i)
{
color[HAL_RED] = (BYTE) (i << 4);
color[HAL_GREEN] = (BYTE) (i << 4);
color[HAL_BLUE] = (BYTE) (i << 4);
_WriteLutEntry(LCD, i, color);
}
break;
default:
break;
}
/*
** Initialize CRT/TV LUT
*/
switch (regCrtTvDisplayMode & 0x07)
{
case 2: /* 4 bpp color */
_WriteLut(CRT | TV, LUT4_Color, 16);
break;
case 3: /* 8 bpp color */
_WriteLut(CRT | TV, LUT8_Color, 256);
break;
default:
break;
}
if (flags & DISP_BLANK)
{
val = seReadRegByte(REG_DISPLAY_MODE);
if (val & 0x01)
{
/*
** Set LCD Blank to OFF (turn on LCD).
*/
seWriteRegByte(REG_LCD_DISPLAY_MODE,
seReadRegByte(REG_LCD_DISPLAY_MODE) & ~0x80);
}
if (val & 0x06)
{
/*
** Set CRT/TV Blank to OFF (turn on CRT/TV).
*/
seWriteRegByte(REG_CRTTV_DISPLAY_MODE,
seReadRegByte(REG_CRTTV_DISPLAY_MODE) & ~0x80);
}
}
if ((seReadRegByte(REG_DISPLAY_MODE) & 0x06) == 0x02)
{
// Ensure that TV PAL/NTSC bit is set to 0 when CRT mode enabled
seWriteRegByte(REG_TV_OUTPUT_CTRL, seReadRegByte(REG_TV_OUTPUT_CTRL) & ~0x01);
}
/*
** Determine how much memory is available.
*/
_MemorySize = seGetInstalledMemorySize();
_seVmemInit(_MemorySize);
/*
** Initialize clock chip
*/
errClock = ERR_OK;
/* First initialize CLKI (MREG in clock chip) */
for (iFreq = 0; iFreq < MAX_FREQ_INDEX; ++iFreq)
{
if (_ClockBits[iFreq].dwFreq == _HalInfo->dwClkI)
break;
}
/*
** Couldn't find CLKI in table
*/
if (iFreq >= MAX_FREQ_INDEX)
errClock = ERR_CLKI_NOT_IN_TABLE;
else
{
if (_GetClockChipBits(iFreq, CLK_MREG, &bits, &szFreq) != ERR_OK)
errClock = ERR_CLKI_NOT_IN_TABLE;
}
if (errClock != ERR_CLKI_NOT_IN_TABLE)
_ProgramClockChip(bits, CLK_VREG1); /* pgm MREG in clock chip, then select VREG1 (power off camera) */
/*
** Next program CLKI2 (VREG0 and VREG1 in clock chip)
*/
for (iFreq = 0; iFreq < MAX_FREQ_INDEX; ++iFreq)
{
if (_ClockBits[iFreq].dwFreq == _HalInfo->dwClkI2)
break;
}
/*
** Couldn't find CLKI2 in table
*/
if (iFreq >= MAX_FREQ_INDEX)
errClock = ERR_CLKI2_NOT_IN_TABLE;
else
{
if (_GetClockChipBits(iFreq, CLK_VREG1, &bits, &szFreq) != ERR_OK)
errClock = ERR_CLKI2_NOT_IN_TABLE;
}
if (errClock != ERR_CLKI2_NOT_IN_TABLE)
_ProgramClockChip(bits, CLK_VREG1); /* pgm VREG1 in clock chip, then select VREG1 (power off camera) */
if (iFreq < MAX_FREQ_INDEX)
{
if (_GetClockChipBits(iFreq, CLK_VREG0, &bits, &szFreq) != ERR_OK)
errClock = ERR_CLKI2_NOT_IN_TABLE;
}
if (errClock != ERR_CLKI2_NOT_IN_TABLE)
_ProgramClockChip(bits, CLK_VREG1); /* pgm VREG0 in clock chip, then select VREG1 (power off camera) */
/*
** Always program VREG2 to FEATCLK for media plug interface.
**
*/
if (_GetClockChipBits(FREQ_FEATCLK, CLK_VREG2, &bits, &szFreq) == ERR_OK)
_ProgramClockChip(bits, CLK_VREG1); /* pgm VREG2 in clock chip, then select VREG1 (power off camera) */
if (DisplayMode == 0)
DisplayMode = seReadRegByte(REG_DISPLAY_MODE);
err = _AutoAllocSurface(DisplayMode);
/*
** Clear all visible display memory.
*/
if (flags & CLEAR_MEM)
seWriteDisplayDwords(0, 0, seGetAvailableMemorySize() / 4);
if (errClock != ERR_OK)
return errClock;
else if ((err == ERR_OK) || (err == ERR_DISPLAY_NOT_ENABLED))
return ERR_OK;
else
return err;
}
/*-------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -