📄 misc.cpp
字号:
// -----------------------------------------------------------------------------
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
// Copyright (c) 2002 Silicon Motion, Inc.
//
// Module Name: misc.cpp
//
// Abstract: miscellaneous functions
//
// Notes:
//
// -----------------------------------------------------------------------------
#include "precomp.h"
#include "dispperf.h"
#include <pwingdi.h>
#ifdef VGXDMA
#include "DMARegs.h"
#endif
extern BOOL g_bSaveSurface;
SCODE SMI::SetPalette(const PALETTEENTRY *src, USHORT firstEntry, USHORT numEntries)
{
int i;
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("GPEVGA::SetPallette()\r\n")));
if (firstEntry < 0 || firstEntry + numEntries > 256)
return(E_INVALIDARG);
for (i=firstEntry; i< numEntries; i++)
{
POKE_32(PANEL_PALETTE_RAM+i*4, src[i].peRed<<16 | src[i].peGreen<<8 | src[i].peBlue);
#ifdef MULTIMONEMU_ENABLE
if (m_SMISettings.m_nDualMonEnabled == 0)
#endif //MULTIMONEMU_ENABLE
POKE_32(CRT_PALETTE_RAM+i*4, src[i].peRed<<16 | src[i].peGreen<<8 | src[i].peBlue);
}
return (S_OK);
}
int SMI::IsPaletteSettable()
{
if (m_pMode)
{
if (m_pMode->Bpp == 8)
{
return TRUE;
}
}
return FALSE;
}
ULONG SMI::GetGraphicsCaps()
{
/*
if (m_pMode)
{
if (m_pMode->Bpp == 16) // if in 16bpp mode, return GCAPS_GRAY16 to denote that we support anti-aliased fonts
{
return GCAPS_GRAY16;
}
}
*/
return 0;
}
void SMI::WaitForNotBusy(void)
{
//DEBUGMSG(GPE_ZONE_ENTER, (TEXT("GPEVGA::WFNB()\r\n")));
#if 0
for (int i = 0x1000000; i > 0; i--)
if (!IS_BUSY)
break;
#else
DWORD dwVal;
#ifdef CMDLIST
while (FIELD_GET(PEEK_32(CMD_INTPR_CTRL), CMD_INTPR_CTRL, STATUS) == CMD_INTPR_CTRL_STATUS_RUNNING);
#endif // CMDLIST
for (int i = 0x1000000; i > 0; i--)
{
dwVal = PEEK_32(CMD_INTPR_STATUS);
if ((FIELD_GET(dwVal, CMD_INTPR_STATUS, 2D_ENGINE) == CMD_INTPR_STATUS_2D_ENGINE_IDLE) &&
(FIELD_GET(dwVal, CMD_INTPR_STATUS, 2D_FIFO) == CMD_INTPR_STATUS_2D_FIFO_EMPTY) &&
(FIELD_GET(dwVal, CMD_INTPR_STATUS, 2D_SETUP) == CMD_INTPR_STATUS_2D_SETUP_IDLE) &&
(FIELD_GET(dwVal, CMD_INTPR_STATUS, CSC_STATUS) == CMD_INTPR_STATUS_CSC_STATUS_IDLE) &&
(FIELD_GET(dwVal, CMD_INTPR_STATUS, 2D_MEMORY_FIFO) == CMD_INTPR_STATUS_2D_MEMORY_FIFO_EMPTY) &&
(FIELD_GET(dwVal, CMD_INTPR_STATUS, COMMAND_FIFO) == CMD_INTPR_STATUS_COMMAND_FIFO_EMPTY) &&
#ifdef VGXDMA
(FIELD_GET(dwVal, CMD_INTPR_STATUS, MEMORY_DMA) == CMD_INTPR_STATUS_MEMORY_DMA_IDLE) &&
#endif
TRUE
)
{
break;
}
}
#endif
}
int SMI::IsBusy(void)
{
//DEBUGMSG(GPE_ZONE_ENTER, (TEXT("GPEVGA::IB()\r\n")));
return IS_BUSY;
}
int SMI::InVBlank()
{
//DEBUGMSG(GPE_ZONE_ENTER, (TEXT("GPEVGA::IVB()\r\n")));
if (PANEL_SCANLINE < (unsigned)(m_nScreenHeightSave-5))
return FALSE;
return TRUE;
}
void SMI::WaitForVBlank()
{
WaitForVerticalSync();
}
void vsyncIntHandlerEntry(SMI* pSMI)
{
pSMI->VSyncIntHandler();
}
void SMI::VSyncIntHandler()
{
#ifndef DISABLE_INTERRUPT_MANAGEMENT
if (m_bVsyncEvent)
{
SetEvent(m_hVsyncEvent);
}
POKE_32(RAW_INT_STATUS, FIELD_SET(0, RAW_INT_STATUS, PANEL_VSYNC, CLEAR));
#endif
}
void SMI::InitVSyncInterrupt()
{
#ifndef DISABLE_INTERRUPT_MANAGEMENT
m_bVsyncEvent = FALSE;
m_hVsyncEvent = CreateEvent(NULL,
FALSE, // Auto-reset
FALSE, // Initially not signaled
NULL);
if (m_hVsyncEvent == NULL)
{
DEBUGMSG(GPE_ZONE_ERROR, (TEXT("SMI::InitVsyncInterrupt Failed!\r\n")));
m_bVsyncEvent = TRUE;
}
// Register PWM interrupt handler
RegisterHandler(
vsyncIntHandlerEntry,
FIELD_SET(0, INT_MASK, PANEL_VSYNC, ENABLE));
#endif //DISABLE_INTERRUPT_MANAGEMENT
}
BOOL SMI::WaitForVerticalSync()
{
#ifdef DISABLE_INTERRUPT_MANAGEMENT
//DEBUGMSG(GPE_ZONE_ENTER, (TEXT("GPEVGA::WFVB()\r\n")));
while ( (PANEL_SCANLINE > (unsigned)m_SMISettings.m_dwCyPanel) );
while ( (PANEL_SCANLINE < (unsigned)(m_SMISettings.m_dwCyPanel-5)) );
return TRUE;
#else // Int Enabled
// WaitForVerticalSync
// This function is called to make the current thread sleep until the next
// vertical retrace interrupt. It returns FALSE if another thread is already
// waiting on the interrupt.
// Local variables.
BOOL retVal = FALSE;
DWORD retWait;
DEBUGMSG(GPE_ZONE_ENTER,(L"WaitForVerticalSync++"));
if (!m_bVsyncEvent) {
// Worst case : we are prempted right after m_bVsyncEvent is set to
// TRUE, and then we hit a vertical retrace. This causes m_bVsyncEvent to
// be harmlessly set with no threads waiting. We also miss that vsync.
m_bVsyncEvent = TRUE;
retWait = WaitForSingleObject(m_hVsyncEvent,
20000);
m_bVsyncEvent = FALSE;
switch (retWait) {
case WAIT_OBJECT_0:
retVal = TRUE;
break;
case WAIT_TIMEOUT:
DEBUGMSG(GPE_ZONE_WARNING, (L"Timeout waiting for vertical retrace!\n"));
break;
case WAIT_FAILED:
DEBUGMSG(GPE_ZONE_ERROR,(L"Wait on vertical retrace failed\n"));
break;
}
}
else {
DEBUGMSG(GPE_ZONE_ERROR, (L"Another thread is already waiting on the vsync!\n"));
}
DEBUGMSG(GPE_ZONE_ENTER,(L"WaitForVerticalSync--"));
return retVal;
#endif
}
/*
void SMI::LockVGA()
{
//DEBUGMSG(GPE_ZONE_ENTER, (TEXT("GPEVGA::LockVGA()\r\n")));
// disable writes to CR0..7
reg_VRE = reg_VRE | 0x80; // reg_CR[0x11]
}
*/
void SMI::UnlockVGA()
{
//DEBUGMSG(GPE_ZONE_ENTER, (TEXT("GPEVGA::UnlockVGA()\r\n")));
// enable writes to CR0..7
//reg_VRE = reg_VRE & 0x7F; // reg_CR[0x11]
}
void SMI::Unlock(void)
{
//DEBUGMSG(GPE_ZONE_ENTER, (TEXT("SMI::Unlock\r\n")));
//reg_LOCK = (reg_LOCK & 0xEF) | 0x40;
}
/*
void SMI::Lock(void)
{
//DEBUGMSG(GPE_ZONE_ENTER, (TEXT("SMI::Lock\r\n")));
reg_LOCK = (reg_LOCK & 0xEF) | 0xA0;
}
*/
ULONG SMI::HandleSMIInfoCommand(ULONG cjIn, PVOID pvIn, ULONG cjOut, PVOID pvOut)
{
int RetVal = 0; // Not Supported
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -