📄 smi.cpp
字号:
#endif // CMDLIST
#ifdef VGXDMA
// Init VGX DMA
InitVGXDMA();
#endif
// Setup Rotation Info
m_nScreenHeightSave = m_pMode->height;
m_nScreenWidthSave = m_pMode->width;
m_iRotate = GetRotateModeFromReg();
SetRotateParams();
// Start Power Management
StartPowerManagement();
// Setup interrupt event
#ifndef DISABLE_INTERRUPT_MANAGEMENT
InitInterrupt();
#endif
InitVSyncInterrupt();
// Init SSP API
InitSSP();
}
#define BLOCK_64K (64*1024)
void SMI::SetupVideoMemory()
{
#ifndef UMA
// Configure memory state
ULONG value = peekRegisterDWord(DRAM_CTRL);
if (rev() == 0xA0) // Configure the memory for revA
{
//value = FIELD_SET(value, DRAM_CTRL, SIZE, 16);
//value = FIELD_SET(value, DRAM_CTRL, COLUMN_SIZE, 512);
value = FIELD_SET(value, DRAM_CTRL, BLOCK_WRITE_PRECHARGE, 4);
value = FIELD_SET(value, DRAM_CTRL, BANKS, 2);
//value = 0x000025C2;
}
else if (rev() == 0xB0)// revB
{
value = FIELD_SET(value, DRAM_CTRL, BANKS, 2);
//value = 0x07F127C0;
}
pokeRegisterDWord(DRAM_CTRL, value);
// Check memory size
m_nVideoMemorySize = m_SMISettings.MaxVideoMemorySize();
// Initialize memory block
for (ULONG offset = m_nVideoMemorySize; offset != 0; offset -= BLOCK_64K)
{
*(PULONG) (m_pLAW + offset - 4) = offset ^ 0xAA551133;
}
// Now, find the last 64kB block with a correct identifier and we have
// found the size of the video memory.
for (offset = m_nVideoMemorySize; offset != 0; offset -= BLOCK_64K)
{
if (*(PULONG) (m_pLAW + offset - 4) == (offset ^ 0xAA551133))
break;
}
// Update the physical size of the video memory.
m_nVideoMemorySize = offset;
m_nVideoMemoryAvail = m_nVideoMemorySize;
// Clear memory
DEBUGMSG(GPE_ZONE_INIT, (TEXT("SMIVGX - Video Memory Size = %d.\r\n"), m_nVideoMemorySize));
memset((PUCHAR) m_pLAW, 0, m_nVideoMemorySize);
#else
ULONG value = peekRegisterDWord(MISC_CTRL);
POKE_32(MISC_CTRL, value |
FIELD_INIT(MISC_CTRL, BURST_LENGTH, 1 )
);
value = peekRegisterDWord(DRAM_CTRL);
value &= 0xFFFF;
value |=
FIELD_INIT(DRAM_CTRL, CPU_BURST, 4 ) |
FIELD_INIT(DRAM_CTRL, CPU_CAS_LATENCY, 3) |
FIELD_INIT(DRAM_CTRL, CPU_SIZE, 64) |
FIELD_INIT(DRAM_CTRL, CPU_COLUMN_SIZE, 512) |
FIELD_INIT(DRAM_CTRL, CPU_ACTIVE_PRECHARGE, 7) |
FIELD_INIT(DRAM_CTRL, CPU_RESET, DISABLE) |
FIELD_INIT(DRAM_CTRL, CPU_BANKS, 4);
pokeRegisterDWord(DRAM_CTRL, value); //value = 24B827C0 ;//0x2CB827C0;
pokeRegisterDWord(SYSTEM_DRAM_CTRL,0xa1080800);
m_nVideoMemorySize = SM501_MAXVIDEOMEMORYSIZE;
m_nVideoMemoryAvail = m_nVideoMemorySize;
DEBUGMSG(1,(TEXT("+SMIVGX - MEMSET\r\n")));
//memset((PUCHAR) m_pLAW, 0, m_nVideoMemorySize);
DEBUGMSG(1,(TEXT("-SMIVGX - MEMSET\r\n")));
#endif
}
//
// SetMode
//
// The main function to set the requested mode. This function can be called
// a couple of times for suspend/resume purposes and setting different modes
// (not currently supported in Windows CE .NET)
//
// Inputs: modeId = The id of the requested mode (not the same as mode number)
// pPalette = Pointer to HPALETTE or NULL
//
// Outputs: pPalette = Palette masks for the current mode, if not NULL
//
// Returns: SCODE value, whether or not SetMode is successful
//
SCODE SMI::SetMode(int modeId, HPALETTE *pPalette)
{
SCODE sc;
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("+SMIVGX::SetMode\r\n")));
if (m_bSetMode)
return S_OK;
m_bSetMode = TRUE;
// Save rotation angle
int iRotate = m_iRotate;
m_iRotate = 0;
SetRotateParams();
// Set Zoom Info
m_dwCxZoom = m_SMISettings.m_dwCxZoom;
m_dwCyZoom = m_SMISettings.m_dwCyZoom;
m_nScreenWidth = m_pMode->width;
m_nScreenHeight = m_pMode->height;
m_nRefreshRate = m_pMode->frequency;
m_nScreenBpp = m_pMode->Bpp;
m_nScreenStride = m_pMode->width * m_nScreenBpp/8;
m_nPanelStride = m_SMISettings.m_dwCxPanel * m_nScreenBpp/8;
m_dwPhysicalModeID = m_pMode->modeId;
int nBPP = m_nScreenBpp/8 - 1;
if (pPalette)
{
switch (m_nScreenBpp)
{
case 8:
*pPalette = EngCreatePalette (PAL_INDEXED,
PALETTE_SIZE,
(ULONG*)_rgbIdentity,
0,
0,
0);
break;
case 16:
case 24:
case 32:
*pPalette = EngCreatePalette (PAL_BITFIELDS,
0,
NULL,
BitMasks[nBPP][0],
BitMasks[nBPP][1],
BitMasks[nBPP][2]);
break;
}
}
// This sets the surface address alignment
m_nSurfaceBitsAlign = 128;
#ifdef DD_ENABLE
if (!m_pVideoMemoryHeap)
m_pVideoMemoryHeap = new SurfaceHeap(m_nVideoMemoryAvail, NULL, NULL, NULL);
#else // ! DD_ENABLE
if (!m_p2DVideoMemory)
m_p2DVideoMemory = new Node2D(m_nScreenWidth, m_nVideoMemoryAvail/m_nScreenStride, 0, 0, m_nSurfaceBitsAlign / m_nScreenBpp);
#endif // DD_ENABLE
if (!m_pPrimarySurface)
{
#ifdef DD_ENABLE
if (FAILED(sc = AllocSurface((DDGPESurf **) &m_pPrimarySurface, m_nScreenWidth,
m_nScreenHeight, m_pMode->format, m_pModeEx->ePixelFormat,
GPE_REQUIRE_VIDEO_MEMORY)))
#else // ! DD_ENABLE
if (FAILED(sc = AllocSurface(&m_pPrimarySurface, m_nScreenWidth, m_nScreenHeight,
m_pMode->format, GPE_REQUIRE_VIDEO_MEMORY)))
#endif // DD_ENABLE
{
RETAILMSG (1, (TEXT("SMIVGX - Couldn't allocate primary surface\r\n")));
return sc;
}
}
memset((PUCHAR) m_pPrimarySurface->Buffer(), 0,
m_nScreenStride * m_nScreenHeight);
// Set Mode after Primary Surface Creation
SetModeHardware(modeId);
#ifdef ALPHA_BLEND_DEMO
CreateAlphaSurface();
#endif
// Restore rotation angle
DynRotate(iRotate);
ZoomAPI(m_nPanningX, m_nPanningY,
m_dwCxZoom, m_dwCyZoom,
m_SMISettings.m_dwCxPanel, m_SMISettings.m_dwCyPanel);
// Disable Overlays if the driver is Stretching the primary surface.
// Stretching uses the video layer, therefore overlays are not supported.
if ((m_dwCxZoom != m_SMISettings.m_dwCxPanel) ||
(m_dwCyZoom != m_SMISettings.m_dwCyPanel))
{
m_SMISettings.m_bOverlayDisabled = 1;
}
SetVisibleSurface((GPESurf *) m_pPrimarySurface);
if (m_nScreenBpp == 8)
{
SetPalette(_rgbIdentity, 0, PALETTE_SIZE);
}
// Initialize Cursor
m_nYHot = 0; m_nXHot = 0;
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("-SMIVGX::SetMode\r\n")));
return S_OK;
}
// Accesses m_dwCxZoom, m_dwCyZoom, m_bZoomEnabled
void SMI::ZoomAPI(int nPanningX, int nPanningY, DWORD dwCxZoom, DWORD dwCyZoom, DWORD dwCxPanel, DWORD dwCyPanel)
{
DWORD dwVideoControl = PEEK_32(VIDEO_DISPLAY_CTRL);
// Setup Zoom
if ((dwCxZoom != dwCxPanel) || (dwCyZoom != dwCyPanel))
{
int hstretch, vstretch;
int hmode, vmode;
// Check and Make Sure that video is off
if (FIELD_GET(dwVideoControl, VIDEO_DISPLAY_CTRL, PLANE) == VIDEO_DISPLAY_CTRL_PLANE_ENABLE)
return;
switch (m_nScreenBpp)
{
case 8:
dwVideoControl = FIELD_SET(dwVideoControl, VIDEO_DISPLAY_CTRL, FORMAT, 8);
break;
case 16:
dwVideoControl = FIELD_SET(dwVideoControl, VIDEO_DISPLAY_CTRL, FORMAT, 16);
break;
case 32:
dwVideoControl = FIELD_SET(dwVideoControl, VIDEO_DISPLAY_CTRL, FORMAT, 32);
break;
}
POKE_32(PANEL_DISPLAY_CTRL,FIELD_SET(PEEK_32(PANEL_DISPLAY_CTRL),PANEL_DISPLAY_CTRL, COLOR_KEY, DISABLE));
// calc horizontal stretch ratio
if (dwCxPanel >= dwCxZoom)
{
hstretch = ((40960 * dwCxZoom / dwCxPanel) + 5) / 10;
hmode = VIDEO_SCALE_HORIZONTAL_MODE_EXPAND;
}
else
{
hstretch = ((40960 * dwCxPanel / dwCxZoom) + 5) / 10;
hmode = VIDEO_SCALE_HORIZONTAL_MODE_SHRINK;
}
// calc vertical stretch ratio
if (dwCyPanel >= dwCyZoom)
{
vstretch = ((40960 * dwCyZoom / dwCyPanel) + 5) / 10;
vmode = VIDEO_SCALE_VERTICAL_MODE_EXPAND;
}
else
{
vstretch = ((40960 * dwCyPanel / dwCyZoom) + 5) / 10;
vmode = VIDEO_SCALE_VERTICAL_MODE_SHRINK;
}
// Enable Interpolation mode
//if (dwCyPanel < dwCyZoom)
dwVideoControl = FIELD_SET(dwVideoControl, VIDEO_DISPLAY_CTRL, VERTICAL_MODE, INTERPOLATE);
//if (dwCxPanel < dwCxZoom)
dwVideoControl = FIELD_SET(dwVideoControl, VIDEO_DISPLAY_CTRL, HORIZONTAL_MODE, INTERPOLATE);
POKE_32(VIDEO_PLANE_TL,
FIELD_VALUE(0, VIDEO_PLANE_TL, TOP, 0) |
FIELD_VALUE(0, VIDEO_PLANE_TL, LEFT, 0) |
0);
POKE_32(VIDEO_PLANE_BR,
FIELD_VALUE(0, VIDEO_PLANE_BR, BOTTOM, dwCyPanel-1) |
FIELD_VALUE(0, VIDEO_PLANE_BR, RIGHT, dwCxPanel-1) |
0);
POKE_32(VIDEO_FB_0_ADDRESS,
FIELD_SET(0, VIDEO_FB_0_ADDRESS, STATUS, PENDING) |
FIELD_SET(0, VIDEO_FB_0_ADDRESS, EXT, LOCAL) |
FIELD_VALUE(0, VIDEO_FB_0_ADDRESS, ADDRESS,
m_pPrimarySurface->OffsetInVideoMemory()+nPanningY*m_nScreenStride+nPanningX*m_nScreenBpp) |
0);
dwVideoControl = FIELD_VALUE(dwVideoControl, VIDEO_DISPLAY_CTRL, PIXEL,
((nPanningX * (m_nScreenBpp/8)) % 16)/(m_nScreenBpp/8));
POKE_32(VIDEO_FB_0_LAST_ADDRESS,
FIELD_SET(0, VIDEO_FB_0_LAST_ADDRESS, EXT, LOCAL) |
FIELD_VALUE(0, VIDEO_FB_0_LAST_ADDRESS, ADDRESS, 0x03FFFFFF) |
0);
POKE_32(VIDEO_FB_WIDTH,
FIELD_VALUE(0, VIDEO_FB_WIDTH, WIDTH, m_nScreenStride) |
FIELD_VALUE(0, VIDEO_FB_WIDTH, OFFSET, m_nScreenStride) |
0);
POKE_32(VIDEO_SCALE,
FIELD_VALUE(0, VIDEO_SCALE, VERTICAL_MODE, vmode) |
FIELD_VALUE(0, VIDEO_SCALE, VERTICAL_SCALE, vstretch) |
FIELD_VALUE(0, VIDEO_SCALE, HORIZONTAL_MODE, hmode) |
FIELD_VALUE(0, VIDEO_SCALE, HORIZONTAL_SCALE, hstretch) |
0);
POKE_32(VIDEO_YUV_CONSTANTS,
FIELD_VALUE(0, VIDEO_YUV_CONSTANTS, Y, 0) |
FIELD_VALUE(0, VIDEO_YUV_CONSTANTS, R, 0xED) |
FIELD_VALUE(0, VIDEO_YUV_CONSTANTS, G, 0xED) |
FIELD_VALUE(0, VIDEO_YUV_CONSTANTS, B, 0xED) |
0);
POKE_32(VIDEO_DISPLAY_CTRL,
FIELD_SET(dwVideoControl, VIDEO_DISPLAY_CTRL, PLANE, ENABLE)
);
m_dwCxZoom = dwCxZoom;
m_dwCyZoom = dwCyZoom;
#ifdef DD_ENABLE
m_pVisibleOverlay = (DDGPESurf *)m_pPrimarySurface;
#endif
m_bZoomEnabled = TRUE;
}
else
{
if (FIELD_GET(dwVideoControl, VIDEO_DISPLAY_CTRL, PLANE) == VIDEO_DISPLAY_CTRL_PLANE_DISABLE)
return;
if (!m_bZoomEnabled)
return;
POKE_32(VIDEO_DISPLAY_CTRL,FIELD_SET(dwVideoControl,VIDEO_DISPLAY_CTRL, PLANE, DISABLE));
m_dwCxZoom = dwCxPanel;
m_dwCyZoom = dwCyPanel;
#ifdef DD_ENABLE
m_pVisibleOverlay = NULL;
#endif
m_bZoomEnabled = FALSE;
}
}
//
// GetModeInfo
//
// Returns the mode info of the requested mode number
//
// Inputs: modeNo = The mode number (0 is the default mode,
// not the same as ModeId)
//
// Outputs: pMode = Mode info of the requested mode number
//
// Returns: SCODE value, whether or not mode info is provided
//
SCODE SMI::GetModeInfo (GPEMode *pMode, int modeNo)
{
if (modeNo != 0)
{
return E_INVALIDARG;
}
*pMode = *m_pMode;
return S_OK;
}
#ifdef DD_ENABLE
//
// GetModeInfo
//
// Returns the mode info of the requested mode number
//
// Inputs: modeNo = The mode number (0 is the default mode,
// not the same as ModeId)
//
// Outputs: pMode = Extended mode info of the requested mode number
//
// Returns: SCODE value, whether or not mode info is provided
//
SCODE SMI::GetModeInfoEx(GPEModeEx *pModeEx, int modeNo)
{
if (modeNo != 0)
{
return E_INVALIDARG;
}
*pModeEx = *m_pModeEx;
return S_OK;
}
#endif
//
// NumModes
//
// Returns the number of modes supported, currently only 1 mode
//
int SMI::NumModes(void)
{
return 1;
}
//
// GetPhysicalVideoMemory
//
// Outputs: pPhysicalMemoryBase = Virtual address of the memory base
// pVideoMemorySize = Video Memory size of the video card
//
void SMI::GetPhysicalVideoMemory(PULONG pPhysicalMemoryBase, PULONG pVideoMemorySize)
{
// The return value should be virtual address
*pPhysicalMemoryBase = (ULONG) m_pLAW;
*pVideoMemorySize = m_nVideoMemorySize;
}
//
// Determines whether the SMI USB driver is present in the system
//
BOOL SMI::IsUSBDriverPresent()
{
HKEY hKey;
if (RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
TEXT("Drivers\\BuiltIn\\SMIVGXUSB"),
0, 0, &hKey) == ERROR_SUCCESS)
{
RegCloseKey(hKey);
return TRUE;
}
return FALSE;
}
//
// Determines whether the SMI Audio driver is present in the system
//
BOOL SMI::IsAudioDriverPresent()
{
BOOL bPresent = FALSE;
HKEY hKey;
if (RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
TEXT("Drivers\\BuiltIn\\PCI\\Template\\WaveDev"),
0, 0, &hKey) == ERROR_SUCCESS)
{
// Try to read Vendor ID
DWORD dwType;
TCHAR dwBuffer[100];
DWORD dwSize = sizeof(dwBuffer);
if (RegQueryValueEx(hKey, TEXT("Dll"), NULL, &dwType,
(LPBYTE)&dwBuffer, &dwSize) == ERROR_SUCCESS)
{
// Compare strings
if (_tcsicmp(dwBuffer, TEXT("VGXaudio.dll")) == 0)
bPresent = TRUE;
}
// Close the handler
RegCloseKey(hKey);
}
return bPresent;
}
//
// Determines whether the SMI UART driver is currently using UART1
//
BOOL SMI::IsUART1Active()
{
return (FIELD_GET(peekRegisterDWord(INT_MASK), INT_MASK, UART1) == INT_MASK_UART1_ENABLE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -