#define PSZ 32
#include "leo.h"
#include "leo_regs.h"
#include "pixmapstr.h"
#include "scrnintstr.h"
#include "cfb.h"
void
LeoDoBitblt(DrawablePtr pSrc, DrawablePtr pDst, int alu, RegionPtr prgnDst,
DDXPointPtr pptSrc, unsigned long planemask)
{
LeoPtr pLeo = LeoGetScreenPrivate (pDst->pScreen);
LeoCommand0 *lc0 = pLeo->lc0;
LeoDraw *ld0 = pLeo->ld0;
BoxPtr pboxTmp;
DDXPointPtr pptTmp;
int nbox;
BoxPtr pboxNext, pboxBase, pbox;
pbox = REGION_RECTS(prgnDst);
nbox = REGION_NUM_RECTS(prgnDst);
pptTmp = pptSrc;
pboxTmp = pbox;
ld0->rop = leoRopTable[alu];
if (pptSrc->y < pbox->y1) {
if (pptSrc->x < pbox->x1) {
pboxTmp=pbox+nbox;
pptTmp=pptSrc+nbox;
while (nbox--){
pboxTmp--;
pptTmp--;
if (pptTmp->y <= pboxTmp->y2) {
lc0->extent = 0x80000000 | (pboxTmp->x2 - pboxTmp->x1 - 1) |
((pboxTmp->y2 - pboxTmp->y1 - 1) << 11);
lc0->src = (pptTmp->x + pboxTmp->x2 - pboxTmp->x1 - 1) |
((pptTmp->y + pboxTmp->y2 - pboxTmp->y1 - 1) << 11);
lc0->copy = (pboxTmp->x2 - 1) | ((pboxTmp->y2 - 1) << 11);
} else {
lc0->extent = (pboxTmp->x2 - pboxTmp->x1 - 1) |
((pboxTmp->y2 - pboxTmp->y1 - 1) << 11);
lc0->src = pptTmp->x | (pptTmp->y << 11);
lc0->copy = pboxTmp->x1 | (pboxTmp->y1 << 11);
}
while (lc0->csr & LEO_CSR_BLT_BUSY);
}
} else {
pboxBase = pboxNext = pbox+nbox-1;
while (pboxBase >= pbox) {
while (pboxNext >= pbox &&
pboxBase->y1 == pboxNext->y1)
pboxNext--;
pboxTmp = pboxNext+1;
pptTmp = pptSrc + (pboxTmp - pbox);
while (pboxTmp <= pboxBase) {
if (pptTmp->y <= pboxTmp->y2) {
lc0->extent = 0x80000000 | (pboxTmp->x2 - pboxTmp->x1 - 1) |
((pboxTmp->y2 - pboxTmp->y1 - 1) << 11);
lc0->src = (pptTmp->x + pboxTmp->x2 - pboxTmp->x1 - 1) |
((pptTmp->y + pboxTmp->y2 - pboxTmp->y1 - 1) << 11);
lc0->copy = (pboxTmp->x2 - 1) | ((pboxTmp->y2 - 1) << 11);
} else {
lc0->extent = (pboxTmp->x2 - pboxTmp->x1 - 1) |
((pboxTmp->y2 - pboxTmp->y1 - 1) << 11);
lc0->src = pptTmp->x | (pptTmp->y << 11);
lc0->copy = pboxTmp->x1 | (pboxTmp->y1 << 11);
}
while (lc0->csr & LEO_CSR_BLT_BUSY);
++pboxTmp;
++pptTmp;
}
pboxBase = pboxNext;
}
}
} else {
if (pptSrc->x < pbox->x1) {
pboxBase = pboxNext = pbox;
while (pboxBase < pbox+nbox) {
while (pboxNext < pbox+nbox &&
pboxNext->y1 == pboxBase->y1)
pboxNext++;
pboxTmp = pboxNext;
pptTmp = pptSrc + (pboxTmp - pbox);
if (pptSrc->y == pbox->y1) {
while (pboxTmp != pboxBase) {
--pboxTmp;
--pptTmp;
lc0->extent = 0x80000000 | (pboxTmp->x2 - pboxTmp->x1 - 1) |
((pboxTmp->y2 - pboxTmp->y1 - 1) << 11);
lc0->src = (pptTmp->x + pboxTmp->x2 - pboxTmp->x1 - 1) |
((pptTmp->y + pboxTmp->y2 - pboxTmp->y1 - 1) << 11);
lc0->copy = (pboxTmp->x2 - 1) | ((pboxTmp->y2 - 1) << 11);
while (lc0->csr & LEO_CSR_BLT_BUSY);
}
} else {
while (pboxTmp != pboxBase) {
--pboxTmp;
--pptTmp;
lc0->extent = (pboxTmp->x2 - pboxTmp->x1 - 1) |
((pboxTmp->y2 - pboxTmp->y1 - 1) << 11);
lc0->src = pptTmp->x | (pptTmp->y << 11);
lc0->copy = pboxTmp->x1 | (pboxTmp->y1 << 11);
while (lc0->csr & LEO_CSR_BLT_BUSY);
}
}
pboxBase = pboxNext;
}
} else {
while (nbox--) {
lc0->extent = (pboxTmp->x2 - pboxTmp->x1 - 1) |
((pboxTmp->y2 - pboxTmp->y1 - 1) << 11);
lc0->src = pptTmp->x | (pptTmp->y << 11);
lc0->copy = pboxTmp->x1 | (pboxTmp->y1 << 11);
while (lc0->csr & LEO_CSR_BLT_BUSY);
pboxTmp++;
pptTmp++;
}
}
}
ld0->rop = LEO_ATTR_RGBE_ENABLE|LEO_ROP_NEW;
}
RegionPtr
LeoCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
GCPtr pGC, int srcx, int srcy, int width, int height, int dstx, int dsty)
{
if (pSrcDrawable->type != DRAWABLE_WINDOW)
return cfbCopyArea (pSrcDrawable, pDstDrawable,
pGC, srcx, srcy, width, height, dstx, dsty);
return cfbBitBlt (pSrcDrawable, pDstDrawable,
pGC, srcx, srcy, width, height, dstx, dsty, (void (*)())LeoDoBitblt, 0);
}