📄 blt.cpp
字号:
//
// if dest rect overlaps src rect on right side,
// start copy from right to left....
//
if (prclDst->left>prclSrc->left)
{
ulCmd |= 0x100;
ulDelta = BYTESPERPIXEL(prclSrc->right-prclSrc->left-1);
ulSrcAddress += ulDelta;
ulDstAddress += ulDelta;
}
//
// same for top/bottom rects
//
if (prclDst->top>prclSrc->top)
{
ulCmd |= 0x200;
ulDelta = (prclSrc->bottom-prclSrc->top-1)*ulSrcSpan;
ulSrcAddress += ulDelta;
ulDstAddress += ulDelta;
}
}
}
//
// wait before touching registers if engine was busy
//
if (BltEngineBusy())
WaitForNotBusy();
if (pBrush!=NULL)
{
DEBUGMSG(CT69K_ZONE_HW,
(TEXT("--loading %dx%d brush\r\n"), pptlBrush->x, pptlBrush->y));
ulCmd |= DownloadBrush( pBrush);
} else
{
DEBUGMSG(CT69K_ZONE_HW,
(TEXT("--loading solid brush (%06x)\r\n"), pBltParms->solidColor));
SetBR( 1, pBltParms->solidColor);
ulCmd |= (3 << 18); // force solid brush
}
SetBR( 0, ulSrcSpan | (ulDstSpan << 16));
SetBR( 4, ulCmd);
SetBR( 6, ulSrcAddress);
SetBR( 7, ulDstAddress);
ULONG ulWidth=BYTESPERPIXEL(prclDst->right - prclDst->left);
ULONG ulHeight=prclDst->bottom - prclDst->top;
SetBR( 8, ulWidth | (ulHeight << 16));
return S_OK;
}
//-----------------------------------------------------------------------
//
// CT69000::AcceleratedFill
//
// hardware accelerated solid color fill
//
//-----------------------------------------------------------------------
SCODE
CT69000::AcceleratedFill(GPEBltParms *pBltParms)
{
DEBUGMSG(CT69K_ZONE_HW,
(TEXT("AcceleratedFill color = 0x%4x\r\n"), pBltParms->solidColor));
DBGBLTPARMS( CT69K_ZONE_HW, pBltParms);
ULONG ulDstSpan=pBltParms->pDst->Stride();
ULONG ulDstAddress=pBltParms->pDst->OffsetInVideoMemory();
ULONG ulWidth=
BYTESPERPIXEL(pBltParms->prclDst->right - pBltParms->prclDst->left);
ULONG ulHeight=pBltParms->prclDst->bottom - pBltParms->prclDst->top;
ULONG ulColor=pBltParms->solidColor;
ulDstAddress += BYTESPERPIXEL(pBltParms->prclDst->left)+
pBltParms->prclDst->top*ulDstSpan;
if (pBltParms->pLookup)
{
ulColor = (pBltParms->pLookup)[ulColor];
}
if (pBltParms->pConvert)
{
ulColor = (pBltParms->pColorConverter->*(pBltParms->pConvert))(ulColor);
}
if (BltEngineBusy())
WaitForNotBusy();
SetBR( 0, ulDstSpan << 16); // set dest. span
SetBR( 1, pBltParms->solidColor); // set bc color
SetBR( 4, (pBltParms->rop4 & 0xff) |
(1<<19) | // force bc color
(1<<18)); // specify mono pattern
SetBR( 7, ulDstAddress);
SetBR( 8, ulWidth | (ulHeight << 16));
return S_OK;
}
//-----------------------------------------------------------------------
//
// CT69000::AcceleratedPatternFill
//
// fill dest. rect with an 8x8 pattern brush
//
//-----------------------------------------------------------------------
SCODE
CT69000::AcceleratedPatternFill(GPEBltParms *pBltParms)
{
DEBUGMSG(CT69K_ZONE_HW, (TEXT("AcceleratedPatternFill\r\n")));
DBGBLTPARMS( CT69K_ZONE_HW, pBltParms);
POINTL *pptlBrush=pBltParms->pptlBrush;
ULONG ulDstSpan=pBltParms->pDst->Stride();
ULONG ulDstAddress=pBltParms->pDst->OffsetInVideoMemory();
ULONG ulWidth=
BYTESPERPIXEL(pBltParms->prclDst->right - pBltParms->prclDst->left);
ULONG ulHeight=pBltParms->prclDst->bottom - pBltParms->prclDst->top;
ULONG ulCmd=pBltParms->rop4 & 0xff;
ulCmd |= (pptlBrush->y & 7) << 20;
if (BltEngineBusy())
WaitForNotBusy();
ulCmd |= DownloadBrush(pBltParms->pBrush);
ulDstAddress += BYTESPERPIXEL(pBltParms->prclDst->left)+
pBltParms->prclDst->top*ulDstSpan;
SetBR( 0, ulDstSpan << 16); // set dest. span
SetBR( 4, ulCmd);
SetBR( 7, ulDstAddress);
SetBR( 8, ulWidth | (ulHeight << 16));
return S_OK;
}
//-----------------------------------------------------------------------
//
// CT69000::DownloadBrush
//
// load brush to pattern memory and return bits for cmd flag
//
//-----------------------------------------------------------------------
ULONG
CT69000::DownloadBrush(GPESurf *pBrush)
{
ULONG ulCmd=0;
volatile PULONG pBrushDst;
PULONG pBrushSrc;
pBrushSrc=(PULONG)pBrush->Buffer();
pBrushDst=(PULONG)m_pPatternMemory;
//
// handcoded routines for download to make it really fast...
//
if (pBrush->Format()==gpe1Bpp)
{
ulCmd |= (1<<18);
pBrushDst[0]=pBrushSrc[0];
pBrushDst[1]=pBrushSrc[1];
} else if (pBrush->Format()==gpe8Bpp)
{
for (INT i=0; i<8; i++)
{
pBrushDst[0]=pBrushSrc[0];
pBrushDst[1]=pBrushSrc[1];
pBrushDst+=2;
pBrushSrc = (PULONG)((PUCHAR)pBrushSrc+pBrush->Stride());
}
} else if (pBrush->Format()==gpe16Bpp)
{
for (INT i=0; i<8; i++)
{
pBrushDst[0]=pBrushSrc[0];
pBrushDst[1]=pBrushSrc[1];
pBrushDst[2]=pBrushSrc[2];
pBrushDst[3]=pBrushSrc[3];
pBrushDst+=4;
pBrushSrc = (PULONG)((PUCHAR)pBrushSrc+pBrush->Stride());
}
} else if (pBrush->Format()==gpe32Bpp)
{
//
// pack 32bpp to 24bpp
//
for (INT i=0; i<8; i++)
{
pBrushDst[0]= (pBrushSrc[0] & 0xffffff) | (pBrushSrc[1] << 24);
pBrushDst[1]=((pBrushSrc[1] & 0xffff00)>> 8) | (pBrushSrc[2] << 16);
pBrushDst[2]=((pBrushSrc[2] & 0xff0000)>> 16) | (pBrushSrc[3] << 8);
pBrushDst[3]= (pBrushSrc[4] & 0xffffff) | (pBrushSrc[5] << 24);
pBrushDst[4]=((pBrushSrc[5] & 0xffff00)>> 8) | (pBrushSrc[6] << 16);
pBrushDst[5]=((pBrushSrc[6] & 0xff0000)>> 16) | (pBrushSrc[7] << 8);
pBrushDst+=8;
pBrushSrc = (PULONG)((PUCHAR)pBrushSrc+pBrush->Stride());
}
} else if (pBrush->Format()==gpe24Bpp)
{
//
// brush for 24bpp is aligned to 32 bytes
//
for (INT i=0; i<8; i++)
{
pBrushDst[0]=pBrushSrc[0];
pBrushDst[1]=pBrushSrc[1];
pBrushDst[2]=pBrushSrc[2];
pBrushDst[3]=pBrushSrc[3];
pBrushDst[4]=pBrushSrc[4];
pBrushDst[5]=pBrushSrc[5];
pBrushDst+=8;
pBrushSrc = (PULONG)((PUCHAR)pBrushSrc+pBrush->Stride());
}
} else
{
DEBUGMSG( 1, (TEXT("unknown brush format! (%d)\r\n"), pBrush->Format()));
}
return ulCmd;
}
//-----------------------------------------------------------------------
//
// CT69000::AcceleratedTextOut1bpp
//
// output one 1bpp character mask to hardware port to write char
// to screen
//
//-----------------------------------------------------------------------
SCODE
CT69000::AcceleratedTextOut1bpp(GPEBltParms *pBltParms)
{
DEBUGMSG(CT69K_ZONE_HW, (TEXT("AcceleratedTextOut1bpp\r\n")));
DBGBLTPARMS( CT69K_ZONE_HW, pBltParms);
//
// note: this textout function works only if surfaces are allocated
// on 16 byte boundaries with a stride mod 16
//
//
// some handy shortcuts for pointers
//
RECTL *prclMask=pBltParms->prclMask;
RECTL *prclDst=pBltParms->prclDst;
GPESurf *pMask=pBltParms->pMask;
GPESurf *pDst=pBltParms->pDst;
LONG lDstSpan =pDst->Stride();
LONG lMaskSpan=pMask->Stride();
ULONG ulAbsMaskSpan=labs(lMaskSpan);
ULONG ulDstAddress=pDst->OffsetInVideoMemory();
ULONG ulLeftClipBits=prclMask->left & 7;
ULONG ulLeftClipBytes=prclMask->left >> 3;
ULONG ulRightClipBits=(ulAbsMaskSpan*8-prclMask->right) & 7;
ULONG ulRightClipBytes=(ulAbsMaskSpan*8-prclMask->right) >> 3;
PUCHAR pBuffer=(PUCHAR)pMask->Buffer();
pBuffer += prclMask->top*lMaskSpan;
ulDstAddress += BYTESPERPIXEL(prclDst->left)+
prclDst->top*lDstSpan;
//
// wait before touching registers if engine was busy
//
if (BltEngineBusy())
WaitForNotBusy();
SetBR( 0, //(ulAbsMaskSpan & 0xffff) |
(lDstSpan << 16));
SetBR( 2, pBltParms->solidColor); // set fg color
SetBR( 3, (2L << 24) | // byte alignment
(ulRightClipBits << 8) | // skip last n bits
ulLeftClipBits // skip first n bits
);
SetBR( 4, 0xcc | // src copy bits
(1<<10) | // Mask is memory port
(1<<12) | // color depth 1bit
(1<<13) // use 1bpp as write mask
);
SetBR( 7, ulDstAddress);
ULONG ulWidth=BYTESPERPIXEL(prclMask->right - prclMask->left);
ULONG ulHeight=prclMask->bottom - prclMask->top;
SetBR( 8, ulWidth | (ulHeight << 16));
volatile PULONG pulDest = (PULONG)&m_pCtrlRegister[CT69000_BITBLT_DATA];
if (ulRightClipBytes==0 &&
ulLeftClipBytes==0 &&
lMaskSpan > 0)
{
PULONG pulSrc = (PULONG)pBuffer;
INT i=(lMaskSpan*ulHeight+3)>>2;
// source is aligned for dword writes!!!
while (i--)
*pulDest=*pulSrc++;
} else
{
INT iRight = ulAbsMaskSpan - ulRightClipBytes;
INT v=0;
ULONG ulData=0;
//
// complicated text out, do it byte by byte
// e.g. WBT outputs several characters a time
// in one call
//
// 69000 accepts only dwords on data port,
// so collect bytes in temp ulData and write
// them when dword is full
//
while (ulHeight!=0)
{
for (INT i=ulLeftClipBytes;i<iRight;i++)
{
ulData |= (ULONG)pBuffer[i] << v;
v += 8;
if (v>=32)
{
*pulDest = ulData;
v = 0;
ulData = 0;
}
}
pBuffer += lMaskSpan;
ulHeight--;
}
//
// write rest of data
//
*pulDest = ulData;
}
//
// chip needs additional write ...otherwise it will hang
//
// writing ulHeight to avoid compiler optimization....
// (compiler optimized *pulDest=0 to and [pulDest],0
// and caused the hardware to hang because of the
// read from the data port)
//
*pulDest=ulHeight;
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -