#include <sys/param.h>
#include <sys/systm.h>
#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wsdisplayvar.h>
#include <dev/rasops/rasops.h>
#include <dev/rasops/rasops_masks.h>
#include <luna88k/dev/maskbits.h>
#include <luna88k/dev/omrasops.h>
#include <machine/board.h>
#define OMFB_FB_WADDR (BMAP_BMP + 8)
int om1_windowmove(struct rasops_info *, u_int16_t, u_int16_t,
u_int16_t, u_int16_t, u_int16_t, u_int16_t, int16_t,
int16_t );
int om4_windowmove(struct rasops_info *, u_int16_t, u_int16_t,
u_int16_t, u_int16_t, u_int16_t, u_int16_t, int16_t,
int16_t );
int
om1_windowmove(struct rasops_info *ri, u_int16_t sx, u_int16_t sy,
u_int16_t dx, u_int16_t dy, u_int16_t cx, u_int16_t cy, int16_t rop,
int16_t planemask )
{
int width;
u_int32_t *psrcLine, *pdstLine;
u_int32_t *psrc;
u_int32_t *pdst;
u_int32_t startmask, endmask;
int nlMiddle;
int nl;
int xoffSrc;
int nstart;
int nend;
int srcStartOver;
width = ri->ri_stride / 4;
if (sy < dy) {
psrcLine = ((u_int32_t *)OMFB_FB_WADDR)
+ ((sy + cy - 1) * width);
pdstLine = ((u_int32_t *)OMFB_FB_WADDR)
+ ((dy + cy - 1) * width);
width = -width;
} else {
psrcLine = ((u_int32_t *)OMFB_FB_WADDR) + (sy * width);
pdstLine = ((u_int32_t *)OMFB_FB_WADDR) + (dy * width);
}
if (cx <= 32) {
int srcBit, dstBit;
pdstLine += (dx >> 5);
psrcLine += (sx >> 5);
psrc = psrcLine;
pdst = pdstLine;
srcBit = sx & 0x1f;
dstBit = dx & 0x1f;
while (cy--) {
getandputrop(P0(psrc), srcBit, dstBit, cx, P0(pdst), rop);
pdst += width;
psrc += width;
}
} else {
maskbits(dx, cx, startmask, endmask, nlMiddle);
if (startmask)
nstart = 32 - (dx & 0x1f);
else
nstart = 0;
if (endmask)
nend = (dx + cx) & 0x1f;
else
nend = 0;
xoffSrc = ((sx & 0x1f) + nstart) & 0x1f;
srcStartOver = ((sx & 0x1f) + nstart) > 31;
if (sx >= dx) {
pdstLine += (dx >> 5);
psrcLine += (sx >> 5);
while (cy--) {
psrc = psrcLine;
pdst = pdstLine;
if (startmask) {
getandputrop(P0(psrc), (sx & 0x1f),
(dx & 0x1f), nstart, P0(pdst), rop);
pdst++;
if (srcStartOver)
psrc++;
}
if (xoffSrc == 0) {
nl = nlMiddle;
while (nl--) {
if (rop == RR_CLEAR)
*P0(pdst) = 0;
else
*P0(pdst) = *P0(psrc);
psrc++;
pdst++;
}
} else {
nl = nlMiddle + 1;
while (--nl) {
if (rop == RR_CLEAR)
*P0(pdst) = 0;
else
getunalignedword(P0(psrc),
xoffSrc, *P0(pdst));
pdst++;
psrc++;
}
}
if (endmask) {
getandputrop(P0(psrc), xoffSrc, 0, nend,
P0(pdst), rop);
}
pdstLine += width;
psrcLine += width;
}
} else {
pdstLine += ((dx + cx) >> 5);
psrcLine += ((sx + cx) >> 5);
if (xoffSrc + nend >= 32)
--psrcLine;
while (cy--) {
psrc = psrcLine;
pdst = pdstLine;
if (endmask) {
getandputrop(P0(psrc), xoffSrc, 0, nend,
P0(pdst), rop);
}
nl = nlMiddle + 1;
while (--nl) {
--psrc;
--pdst;
if (rop == RR_CLEAR)
*P0(pdst) = 0;
else
getunalignedword(P0(psrc), xoffSrc,
*P0(pdst));
}
if (startmask) {
if (srcStartOver)
--psrc;
--pdst;
getandputrop(P0(psrc), (sx & 0x1f),
(dx & 0x1f), nstart, P0(pdst), rop);
}
pdstLine += width;
psrcLine += width;
}
}
}
return (0);
}
int
om4_windowmove(struct rasops_info *ri, u_int16_t sx, u_int16_t sy,
u_int16_t dx, u_int16_t dy, u_int16_t cx, u_int16_t cy, int16_t rop,
int16_t planemask )
{
int width;
u_int32_t *psrcLine, *pdstLine;
u_int32_t *psrc;
u_int32_t *pdst;
u_int32_t startmask, endmask;
int nlMiddle;
int nl;
int xoffSrc;
int nstart;
int nend;
int srcStartOver;
width = ri->ri_stride / 4;
if (sy < dy) {
psrcLine = ((u_int32_t *)OMFB_FB_WADDR)
+ ((sy + cy - 1) * width);
pdstLine = ((u_int32_t *)OMFB_FB_WADDR)
+ ((dy + cy - 1) * width);
width = -width;
} else {
psrcLine = ((u_int32_t *)OMFB_FB_WADDR) + (sy * width);
pdstLine = ((u_int32_t *)OMFB_FB_WADDR) + (dy * width);
}
if (cx <= 32) {
int srcBit, dstBit;
pdstLine += (dx >> 5);
psrcLine += (sx >> 5);
psrc = psrcLine;
pdst = pdstLine;
srcBit = sx & 0x1f;
dstBit = dx & 0x1f;
while (cy--) {
getandputrop(P0(psrc), srcBit, dstBit, cx, P0(pdst), rop);
getandputrop(P1(psrc), srcBit, dstBit, cx, P1(pdst), rop);
getandputrop(P2(psrc), srcBit, dstBit, cx, P2(pdst), rop);
getandputrop(P3(psrc), srcBit, dstBit, cx, P3(pdst), rop);
pdst += width;
psrc += width;
}
} else {
maskbits(dx, cx, startmask, endmask, nlMiddle);
if (startmask)
nstart = 32 - (dx & 0x1f);
else
nstart = 0;
if (endmask)
nend = (dx + cx) & 0x1f;
else
nend = 0;
xoffSrc = ((sx & 0x1f) + nstart) & 0x1f;
srcStartOver = ((sx & 0x1f) + nstart) > 31;
if (sx >= dx) {
pdstLine += (dx >> 5);
psrcLine += (sx >> 5);
while (cy--) {
psrc = psrcLine;
pdst = pdstLine;
if (startmask) {
getandputrop(P0(psrc), (sx & 0x1f),
(dx & 0x1f), nstart, P0(pdst), rop);
getandputrop(P1(psrc), (sx & 0x1f),
(dx & 0x1f), nstart, P1(pdst), rop);
getandputrop(P2(psrc), (sx & 0x1f),
(dx & 0x1f), nstart, P2(pdst), rop);
getandputrop(P3(psrc), (sx & 0x1f),
(dx & 0x1f), nstart, P3(pdst), rop);
pdst++;
if (srcStartOver)
psrc++;
}
if (xoffSrc == 0) {
nl = nlMiddle;
while (nl--) {
if (rop == RR_CLEAR) {
*P0(pdst) = 0;
*P1(pdst) = 0;
*P2(pdst) = 0;
*P3(pdst) = 0;
} else {
*P0(pdst) = *P0(psrc);
*P1(pdst) = *P1(psrc);
*P2(pdst) = *P2(psrc);
*P3(pdst) = *P3(psrc);
}
psrc++;
pdst++;
}
} else {
nl = nlMiddle + 1;
while (--nl) {
if (rop == RR_CLEAR) {
*P0(pdst) = 0;
*P1(pdst) = 0;
*P2(pdst) = 0;
*P3(pdst) = 0;
} else {
getunalignedword(P0(psrc),
xoffSrc, *P0(pdst));
getunalignedword(P1(psrc),
xoffSrc, *P1(pdst));
getunalignedword(P2(psrc),
xoffSrc, *P2(pdst));
getunalignedword(P3(psrc),
xoffSrc, *P3(pdst));
}
pdst++;
psrc++;
}
}
if (endmask) {
getandputrop(P0(psrc), xoffSrc, 0, nend,
P0(pdst), rop);
getandputrop(P1(psrc), xoffSrc, 0, nend,
P1(pdst), rop);
getandputrop(P2(psrc), xoffSrc, 0, nend,
P2(pdst), rop);
getandputrop(P3(psrc), xoffSrc, 0, nend,
P3(pdst), rop);
}
pdstLine += width;
psrcLine += width;
}
} else {
pdstLine += ((dx + cx) >> 5);
psrcLine += ((sx + cx) >> 5);
if (xoffSrc + nend >= 32)
--psrcLine;
while (cy--) {
psrc = psrcLine;
pdst = pdstLine;
if (endmask) {
getandputrop(P0(psrc), xoffSrc, 0, nend,
P0(pdst), rop);
getandputrop(P1(psrc), xoffSrc, 0, nend,
P1(pdst), rop);
getandputrop(P2(psrc), xoffSrc, 0, nend,
P2(pdst), rop);
getandputrop(P3(psrc), xoffSrc, 0, nend,
P3(pdst), rop);
}
nl = nlMiddle + 1;
while (--nl) {
--psrc;
--pdst;
if (rop == RR_CLEAR) {
*P0(pdst) = 0;
*P1(pdst) = 0;
*P2(pdst) = 0;
*P3(pdst) = 0;
} else {
getunalignedword(P0(psrc),
xoffSrc, *P0(pdst));
getunalignedword(P1(psrc),
xoffSrc, *P1(pdst));
getunalignedword(P2(psrc),
xoffSrc, *P2(pdst));
getunalignedword(P3(psrc),
xoffSrc, *P3(pdst));
}
}
if (startmask) {
if (srcStartOver)
--psrc;
--pdst;
getandputrop(P0(psrc), (sx & 0x1f),
(dx & 0x1f), nstart, P0(pdst), rop);
getandputrop(P1(psrc), (sx & 0x1f),
(dx & 0x1f), nstart, P1(pdst), rop);
getandputrop(P2(psrc), (sx & 0x1f),
(dx & 0x1f), nstart, P2(pdst), rop);
getandputrop(P3(psrc), (sx & 0x1f),
(dx & 0x1f), nstart, P3(pdst), rop);
}
pdstLine += width;
psrcLine += width;
}
}
}
return (0);
}