📄 ct69000.cpp
字号:
while (IsBusy())
{ i--;
if (i==0)
{
//
// Thats no good: means that blt engine hangs...
// if we end up here we have to check our blts for bugs
//
#ifdef DEBUG
DEBUGMSG( 1,
(TEXT("CT69000::WaitForNotBusy -- blt engine still busy")));
DebugBreak();
#endif
//
// reset blt engine
//
SetXR( 0x20, m_ucBitBlt|2);
SetXR( 0x20, m_ucBitBlt);
break;
}
}
}
//-----------------------------------------------------------------------
//
// CT69000::ScanLine
//
// return scanline which electron beam just displays
//
//-----------------------------------------------------------------------
INT
CT69000::ScanLine()
{
DWORD dwMSB, dwLSB;
//
// make sure LSB didn't overrun while we read LSB
//
do {
dwMSB=GetMR(0x44);
dwLSB=GetMR(0x43);
} while (dwMSB!=GetMR(0x44));
return dwLSB+(dwMSB<<8);
}
//-----------------------------------------------------------------------
//
// CT69000::IsFlipBusy
//
//-----------------------------------------------------------------------
BOOL
CT69000::FlipInProgress()
{
return GetCR(0x40) & 0x80;
}
//-----------------------------------------------------------------------
//
// CT69000::FlipTo
//
//
//
//
//-----------------------------------------------------------------------
VOID
CT69000::FlipTo( DWORD dwNewBase)
{
//
// C&T69k wants offset in DWORDS
//
dwNewBase >>= 2;
SetCR( 0xc, (BYTE)(dwNewBase >> 8));
SetCR( 0xd, (BYTE) dwNewBase );
SetCR( 0x40,(BYTE)((dwNewBase >> 16) | 0x80));
}
#if DXPAK
//-----------------------------------------------------------------------
//
// CT69000::ResetOverlay()
//
// reset overlay registers
//
//-----------------------------------------------------------------------
VOID
CT69000::ResetOverlay()
{
//
// init overlay functionality for DirectX overlays
//
DEBUGMSG(CT69K_ZONE_INIT, (TEXT("--MR caps: %02x\r\n"), GetMR(0)));
DEBUGMSG(CT69K_ZONE_INIT, (TEXT("--line: %2d\r\n"), GetMR(0x43) + GetMR(0x44)*256));
SetMR( 0x1e, 0); // reset playback control registers
SetMR( 0x1f, 0);
SetMR( 0x3c, 0); // disable overlay
SetXR( 0xd0, GetXR(0xd0) | 0x10);
for (int i=2; i<=0x17; i++)
SetMR( i, 0);
}
#endif
//-----------------------------------------------------------------------
//
// CT69000::SetOvlFormat
//
// set bpp format of overlay surface (RGB555/RGB565/YUV)
//
// dwOvlFormat---CT69000_OVLFORMAT_RGB565
// CT69000_OVLFORMAT_RGB555
// CT69000_OVLFORMAT_YUV
//
//-----------------------------------------------------------------------
VOID
CT69000::SetOvlFormat( DWORD dwOvlFormat)
{
BYTE bPC2=GetMR(0x1f) & ~0xf;
switch (dwOvlFormat)
{
case CT69000_OVLFORMAT_RGB565:
bPC2 |= 8;
break;
case CT69000_OVLFORMAT_RGB555:
bPC2 |= 9;
break;
case CT69000_OVLFORMAT_YUV:
// do nothing
break;
}
SetMR( 0x1f, bPC2);
}
//-----------------------------------------------------------------------
//
// CT69000::OverlayOn()
//
// turn on overlay
//
//-----------------------------------------------------------------------
VOID
CT69000::OverlayOn()
{
SetMR(0x20, 0xfc);
SetMR(0x3c, (GetMR(0x3c)&~0x20)|5); // enable overlay
m_bOverlayOn=TRUE;
}
//-----------------------------------------------------------------------
//
// CT69000::OverlayOff()
//
// turn off overlay
//
//-----------------------------------------------------------------------
VOID
CT69000::OverlayOff()
{
SetMR( 0x3c, GetMR(0x3c)&~1); // disable overlay
m_bOverlayOn=FALSE;
}
//-----------------------------------------------------------------------
//
// CT69000::ColorKeyOn
//
// turn on dest. color key
//
//-----------------------------------------------------------------------
VOID
CT69000::ColorKeyOn()
{
SetMR( 0x3c, (GetMR(0x3c)&~0xc0)|2);
}
//-----------------------------------------------------------------------
//
// CT69000::ColorKeyOff()
//
// turn off overlay chroma key
//
//-----------------------------------------------------------------------
VOID
CT69000::ColorKeyOff()
{
SetMR( 0x3c, GetMR(0x3c)&~2); // disable key
}
//-----------------------------------------------------------------------
//
// CT69000::SetOvlPTR1
//
// ulBase--base address of overlay pointer 1
//
//-----------------------------------------------------------------------
VOID
CT69000::SetOvlPTR1( ULONG ulBase)
{
ulBase += m_ulOvlBaseOffset;
SetMR(0x22, (BYTE)ulBase);
SetMR(0x23,(BYTE)(ulBase>>8));
SetMR(0x24,(BYTE)(ulBase>>16));
}
//-----------------------------------------------------------------------
//
// CT69000::SetOvlPTR2
//
// ulBase--base address of overlay pointer 2
//
//-----------------------------------------------------------------------
VOID
CT69000::SetOvlPTR2( ULONG ulBase)
{
ulBase += m_ulOvlBaseOffset;
SetMR(0x25, (BYTE)ulBase);
SetMR(0x26,(BYTE)(ulBase>>8));
SetMR(0x27,(BYTE)(ulBase>>16));
}
//-----------------------------------------------------------------------
//
// CT69000::SetOverlayWindow
//
// ulStride---stride of src surface
// lpSrcWindow---src rect of overlay
// lpDstWindow---destination window for overlay on primary surface
//
//-----------------------------------------------------------------------
ULONG
CT69000::SetOverlayWindow(
ULONG ulStride,
LPRECTL lpSrc,
LPRECTL lpDst
)
{
ULONG ulDstWidth =lpDst->right -lpDst->left;
ULONG ulDstHeight=lpDst->bottom-lpDst->top;
if (lpSrc!=NULL)
{
ULONG ulBaseOffset=lpSrc->left+lpSrc->top*ulStride;
ULONG ulSrcWidth =lpSrc->right -lpSrc->left;
ULONG ulSrcHeight=lpSrc->bottom-lpSrc->top;
ULONG ulHZoom=0, ulVZoom=0;
if (ulDstWidth!=ulSrcWidth)
{
if (ulDstWidth > ulSrcWidth)
{
ulHZoom=((ulSrcWidth*0x100)/ulDstWidth) & ~3;
}
}
if (ulDstHeight!=ulSrcHeight)
{
if (ulDstHeight > ulSrcHeight)
{
ulVZoom=((ulSrcHeight*0x100)/ulDstHeight) & ~3;
}
}
BYTE bPC1=GetMR(0x1e) & ~0xc;
BYTE bPC2=GetMR(0x1f) & ~0xf0;
if (ulHZoom)
{
bPC1 |= 0x4; // enable h-zoom
bPC2 |= 0x20; // enable h-interpolation
SetMR( 0x32, (BYTE)ulHZoom);
}
if (ulVZoom)
{
bPC1 |= 0x8; // enable v-zoom
bPC2 |= 0x80; // enable v-interpolation
SetMR( 0x33, (BYTE)ulVZoom);
}
SetMR( 0x1e, bPC1);
SetMR( 0x1f, bPC2);
m_rOvlSrcWindow = *lpSrc;
m_ulOvlBaseOffset = ulBaseOffset;
}
if (ulStride != 0)
{
SetMR( 0x28, (BYTE) (ulStride/8-1));
SetMR( 0x34, (BYTE) (ulDstWidth/4-1));
}
ULONG ulLeft =lpDst->left+m_ulOvlXOffset;
ULONG ulRight=lpDst->right+m_ulOvlXOffset-1;
ULONG ulTop =lpDst->top+m_ulOvlYOffset;
ULONG ulBottom=lpDst->bottom+m_ulOvlYOffset-1;
SetMR( 0x2a, (BYTE) ulLeft);
SetMR( 0x2b, (BYTE) (ulLeft >> 8));
SetMR( 0x2c, (BYTE) ulRight);
SetMR( 0x2d, (BYTE) (ulRight >> 8));
SetMR( 0x2e, (BYTE) ulTop);
SetMR( 0x2f, (BYTE) (ulTop >> 8));
SetMR( 0x30, (BYTE) ulBottom);
SetMR( 0x31, (BYTE) (ulBottom >> 8));
m_rOvlDstWindow = *lpDst;
return m_ulOvlBaseOffset;
}
//-----------------------------------------------------------------------
//
// CT69000::SetOverlayPosition
//
// ulX---x position of overlay window
// ulY---y position of overlay window
//
//-----------------------------------------------------------------------
VOID
CT69000::SetOverlayPosition( ULONG ulX, ULONG ulY)
{
ULONG ulWidth, ulHeight;
RECTL rNewWindow;
ulWidth =m_rOvlDstWindow.right-m_rOvlDstWindow.left;
ulHeight=m_rOvlDstWindow.bottom-m_rOvlDstWindow.top;
rNewWindow.left=ulX;
rNewWindow.top =ulY;
rNewWindow.right=ulX+ulWidth;
rNewWindow.bottom=ulY+ulHeight;
SetOverlayWindow( 0, NULL, &rNewWindow);
}
//-----------------------------------------------------------------------
//
// SetColorKey
//
// dwKey---destination color key for overlay (BGR)
//
//-----------------------------------------------------------------------
VOID CT69000::SetColorKey( DWORD dwKey)
{
DWORD dwMask;
BYTE bR,bG,bB;
switch (m_pMode->format)
{
case gpe8Bpp:
dwMask=0xffffff00;
bB=(BYTE)dwKey;
bG=0;
bR=0;
break;
case gpe16Bpp:
// always assume 565
dwMask=0xff070307;
bB=(BYTE)((dwKey & 0x001f) << 3);
bG=(BYTE)((dwKey & 0x07e0) >> 3);
bR=(BYTE)((dwKey & 0xf800) >> 8);
break;
case gpe24Bpp:
dwMask=0xff000000;
bB=(BYTE)(dwKey);
bG=(BYTE)(dwKey>>8);
bR=(BYTE)(dwKey>>16);
break;
}
SetMR( 0x42, (BYTE) dwMask);
SetMR( 0x41, (BYTE) (dwMask >> 8));
SetMR( 0x40, (BYTE) (dwMask >> 16));
SetMR( 0x3f, bB);
SetMR( 0x3e, bG);
SetMR( 0x3d, bR);
}
//-----------------------------------------------------------------------
//
// CT69000::OvlFlipTo
//
// flip overlay to new base address on next VSync. Should not be called
// if overlay flip is still busy.
//
//-----------------------------------------------------------------------
VOID
CT69000::OvlFlipTo ( ULONG ulBase)
{
INT iCurrentBase;
BYTE bPC3;
iCurrentBase = (GetMR( 0x21) >> 1) & 1;
bPC3 = GetMR(0x20) & ~0x38;
bPC3 |= 0x24; // trigger on next Vsync
if (iCurrentBase==0)
{
bPC3 |= 0x10;
SetOvlPTR2( ulBase);
} else
{
SetOvlPTR1( ulBase);
}
SetMR( 0x20, bPC3);
}
//-----------------------------------------------------------------------
//
// CT69000::OvlFlipBusy()
//
// return TRUE if overlay has not flipped yet to next image
//
//-----------------------------------------------------------------------
BOOL
CT69000::OvlFlipBusy()
{
return GetMR( 0x21) & 1;
}
//-----------------------------------------------------------------------
//
// CT69000::DrvEscape()
//
//-----------------------------------------------------------------------
ULONG
CT69000::DrvEscape(
SURFOBJ *pso,
ULONG iEsc,
ULONG cjIn,
PVOID pvIn,
ULONG cjOut,
PVOID pvOut)
{
int RetVal=0;
#if CURSORDEBUG
switch (iEsc)
{
case ESCSETDEBUGMODE:
if (cjIn>=sizeof(ULONG))
{
m_bBltEmulation=*((PULONG)pvIn);
//RETAILMSG( 1,
// (TEXT("DrvEscape:: acceleration now (%d)\r\n"), m_bBltEmulation));
}
RetVal=m_bBltEmulation;
break;
case QUERYESCSUPPORT :
switch (*(DWORD *)pvIn)
{
case ESCSETDEBUGMODE:
RetVal=1;
break;
}
break;
default:
return GPE::DrvEscape( pso, iEsc, cjIn, pvIn, cjOut, pvOut);
}
#else
return GPE::DrvEscape( pso, iEsc, cjIn, pvIn, cjOut, pvOut);
#endif
return RetVal;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -