ast_cursor.c revision de78e416
115fb4814Smrg/*
215fb4814Smrg * Copyright (c) 2005 ASPEED Technology Inc.
315fb4814Smrg *
415fb4814Smrg * Permission to use, copy, modify, distribute, and sell this software and its
515fb4814Smrg * documentation for any purpose is hereby granted without fee, provided that
615fb4814Smrg * the above copyright notice appear in all copies and that both that
715fb4814Smrg * copyright notice and this permission notice appear in supporting
815fb4814Smrg * documentation, and that the name of the authors not be used in
915fb4814Smrg * advertising or publicity pertaining to distribution of the software without
1015fb4814Smrg * specific, written prior permission.  The authors makes no representations
1115fb4814Smrg * about the suitability of this software for any purpose.  It is provided
1215fb4814Smrg * "as is" without express or implied warranty.
1315fb4814Smrg *
1415fb4814Smrg * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
1515fb4814Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
1615fb4814Smrg * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
1715fb4814Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
1815fb4814Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
1915fb4814Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2015fb4814Smrg * PERFORMANCE OF THIS SOFTWARE.
2115fb4814Smrg */
2215fb4814Smrg
2315fb4814Smrg#ifdef HAVE_CONFIG_H
2415fb4814Smrg#include <config.h>
2515fb4814Smrg#endif
2615fb4814Smrg#include "xf86.h"
2715fb4814Smrg#include "xf86_OSproc.h"
2815fb4814Smrg#include "xf86Resources.h"
2915fb4814Smrg#include "xf86RAC.h"
3015fb4814Smrg#include "xf86cmap.h"
3115fb4814Smrg#include "compiler.h"
3215fb4814Smrg#include "mibstore.h"
3315fb4814Smrg#include "vgaHW.h"
3415fb4814Smrg#include "mipointer.h"
3515fb4814Smrg#include "micmap.h"
3615fb4814Smrg
3715fb4814Smrg#include "fb.h"
3815fb4814Smrg#include "regionstr.h"
3915fb4814Smrg#include "xf86xv.h"
4015fb4814Smrg#include <X11/extensions/Xv.h>
4115fb4814Smrg#include "vbe.h"
4215fb4814Smrg
4315fb4814Smrg#include "xf86PciInfo.h"
4415fb4814Smrg#include "xf86Pci.h"
4515fb4814Smrg
4615fb4814Smrg/* framebuffer offscreen manager */
4715fb4814Smrg#include "xf86fbman.h"
4815fb4814Smrg
4915fb4814Smrg/* include xaa includes */
5015fb4814Smrg#include "xaa.h"
5115fb4814Smrg#include "xaarop.h"
5215fb4814Smrg
5315fb4814Smrg/* H/W cursor support */
5415fb4814Smrg#include "xf86Cursor.h"
5515fb4814Smrg#include "cursorstr.h"
5615fb4814Smrg
5715fb4814Smrg/* Driver specific headers */
5815fb4814Smrg#include "ast.h"
5915fb4814Smrg
6015fb4814Smrg#ifdef	HWC
6115fb4814Smrg/* Prototype type declaration */
6215fb4814SmrgBool ASTCursorInit(ScreenPtr pScreen);
6315fb4814SmrgBool bInitHWC(ScrnInfoPtr pScrn, ASTRecPtr pAST);
6415fb4814Smrgstatic void ASTShowCursor(ScrnInfoPtr pScrn);
65de78e416Smrgvoid ASTHideCursor(ScrnInfoPtr pScrn);
6615fb4814Smrgstatic void ASTSetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
6715fb4814Smrgstatic void ASTSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
6815fb4814Smrgstatic void ASTLoadCursorImage(ScrnInfoPtr pScrn, UCHAR *src);
6915fb4814Smrgstatic Bool ASTUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs);
7015fb4814Smrgstatic void ASTLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs);
7115fb4814Smrgstatic Bool ASTUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs);
7215fb4814Smrg
7315fb4814Smrgstatic void ASTFireCursor(ScrnInfoPtr pScrn);
7415fb4814Smrg
7515fb4814SmrgBool
7615fb4814SmrgASTCursorInit(ScreenPtr pScreen)
7715fb4814Smrg{
7815fb4814Smrg    ScrnInfoPtr	pScrn = xf86Screens[pScreen->myNum];
7915fb4814Smrg    ASTRecPtr 	pAST = ASTPTR(pScrn);
8015fb4814Smrg    xf86CursorInfoPtr infoPtr;
8115fb4814Smrg
8215fb4814Smrg    infoPtr = xf86CreateCursorInfoRec();
8315fb4814Smrg    if(!infoPtr) return FALSE;
8415fb4814Smrg
8515fb4814Smrg    pAST->HWCInfoPtr = infoPtr;
8615fb4814Smrg
8715fb4814Smrg    infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
8815fb4814Smrg                     HARDWARE_CURSOR_INVERT_MASK |
8915fb4814Smrg                     HARDWARE_CURSOR_BIT_ORDER_MSBFIRST;
9015fb4814Smrg
9115fb4814Smrg    infoPtr->MaxWidth  = MAX_HWC_WIDTH;
9215fb4814Smrg    infoPtr->MaxHeight = MAX_HWC_HEIGHT;
9315fb4814Smrg    infoPtr->ShowCursor = ASTShowCursor;
9415fb4814Smrg    infoPtr->HideCursor = ASTHideCursor;
9515fb4814Smrg    infoPtr->SetCursorPosition = ASTSetCursorPosition;
9615fb4814Smrg    infoPtr->SetCursorColors = ASTSetCursorColors;
9715fb4814Smrg    infoPtr->LoadCursorImage = ASTLoadCursorImage;
9815fb4814Smrg    infoPtr->UseHWCursor = ASTUseHWCursor;
9915fb4814Smrg#ifdef ARGB_CURSOR
10015fb4814Smrg    infoPtr->UseHWCursorARGB = ASTUseHWCursorARGB;
10115fb4814Smrg    infoPtr->LoadCursorARGB = ASTLoadCursorARGB;
10215fb4814Smrg#endif
10315fb4814Smrg
10415fb4814Smrg    return(xf86InitCursor(pScreen, infoPtr));
10515fb4814Smrg
10615fb4814Smrg}
10715fb4814Smrg
10815fb4814SmrgBool bInitHWC(ScrnInfoPtr pScrn, ASTRecPtr pAST)
10915fb4814Smrg{
11015fb4814Smrg    ScreenPtr	pScreen;
11115fb4814Smrg
11215fb4814Smrg    /* init cursor cache info */
11315fb4814Smrg    /* Set HWC_NUM in Options instead */
11415fb4814Smrg    /* pAST->HWCInfo.HWC_NUM = DEFAULT_HWC_NUM; */
11515fb4814Smrg    pAST->HWCInfo.HWC_NUM_Next = 0;
11615fb4814Smrg
11715fb4814Smrg    /* allocate HWC cache */
11815fb4814Smrg    if (!pAST->pHWCPtr) {
11915fb4814Smrg        pScreen = screenInfo.screens[pScrn->scrnIndex];
12015fb4814Smrg        pAST->pHWCPtr = xf86AllocateOffscreenLinear (pScreen, (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM, HWC_ALIGN, NULL, NULL, NULL);
12115fb4814Smrg
12215fb4814Smrg        if (!pAST->pHWCPtr) {
12315fb4814Smrg           xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Allocate HWC Cache failed \n");
12415fb4814Smrg           return (FALSE);
12515fb4814Smrg        }
12615fb4814Smrg
12715fb4814Smrg        pAST->HWCInfo.ulHWCOffsetAddr  = pAST->pHWCPtr->offset*((pScrn->bitsPerPixel + 1) / 8);
12815fb4814Smrg        pAST->HWCInfo.pjHWCVirtualAddr = pAST->FBVirtualAddr + pAST->HWCInfo.ulHWCOffsetAddr;
12915fb4814Smrg    }
13015fb4814Smrg
13115fb4814Smrg    return (TRUE);
13215fb4814Smrg}
13315fb4814Smrg
13415fb4814Smrg
13515fb4814Smrgstatic void
13615fb4814SmrgASTShowCursor(ScrnInfoPtr pScrn)
13715fb4814Smrg{
13815fb4814Smrg    ASTRecPtr   pAST = ASTPTR(pScrn);
13915fb4814Smrg    UCHAR 	jReg;
14015fb4814Smrg
14115fb4814Smrg    jReg= 0x02;
14215fb4814Smrg    if (pAST->HWCInfo.cursortype ==HWC_COLOR)
14315fb4814Smrg        jReg |= 0x01;
14415fb4814Smrg
14515fb4814Smrg    SetIndexRegMask(CRTC_PORT, 0xCB, 0xFC, jReg);	/* enable mono */
14615fb4814Smrg
14715fb4814Smrg}
14815fb4814Smrg
149de78e416Smrgvoid
15015fb4814SmrgASTHideCursor(ScrnInfoPtr pScrn)
15115fb4814Smrg{
15215fb4814Smrg    ASTRecPtr  pAST = ASTPTR(pScrn);
15315fb4814Smrg
15415fb4814Smrg    SetIndexRegMask(CRTC_PORT, 0xCB, 0xFC, 0x00);	/* disable HWC */
15515fb4814Smrg
15615fb4814Smrg}
15715fb4814Smrg
15815fb4814Smrgstatic void
15915fb4814SmrgASTSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
16015fb4814Smrg{
16115fb4814Smrg    ASTRecPtr	pAST = ASTPTR(pScrn);
16215fb4814Smrg    DisplayModePtr mode = pAST->ModePtr;
16315fb4814Smrg    int		x_offset, y_offset;
16415fb4814Smrg    UCHAR 	*pjSignature;
16515fb4814Smrg
16615fb4814Smrg    /* Set cursor info to Offscreen */
16715fb4814Smrg    pjSignature = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next + HWC_SIZE;
16815fb4814Smrg    *((ULONG *) (pjSignature + HWC_SIGNATURE_X)) = x;
16915fb4814Smrg    *((ULONG *) (pjSignature + HWC_SIGNATURE_Y)) = y;
17015fb4814Smrg
17115fb4814Smrg    x_offset = pAST->HWCInfo.offset_x;
17215fb4814Smrg    y_offset = pAST->HWCInfo.offset_y;
17315fb4814Smrg
17415fb4814Smrg    if(x < 0) {
17515fb4814Smrg       x_offset = (-x) + pAST->HWCInfo.offset_x;
17615fb4814Smrg       x = 0;
17715fb4814Smrg    }
17815fb4814Smrg
17915fb4814Smrg    if(y < 0) {
18015fb4814Smrg       y_offset = (-y) + pAST->HWCInfo.offset_y;
18115fb4814Smrg       y = 0;
18215fb4814Smrg    }
18315fb4814Smrg
18415fb4814Smrg    if(mode->Flags & V_DBLSCAN)  y *= 2;
18515fb4814Smrg
18615fb4814Smrg    /* Set to Reg. */
18715fb4814Smrg    SetIndexReg(CRTC_PORT, 0xC2, (UCHAR) (x_offset));
18815fb4814Smrg    SetIndexReg(CRTC_PORT, 0xC3, (UCHAR) (y_offset));
18915fb4814Smrg    SetIndexReg(CRTC_PORT, 0xC4, (UCHAR) (x & 0xFF));
19015fb4814Smrg    SetIndexReg(CRTC_PORT, 0xC5, (UCHAR) ((x >> 8) & 0x0F));
19115fb4814Smrg    SetIndexReg(CRTC_PORT, 0xC6, (UCHAR) (y & 0xFF));
19215fb4814Smrg    SetIndexReg(CRTC_PORT, 0xC7, (UCHAR) ((y >> 8) & 0x07));
19315fb4814Smrg
19415fb4814Smrg    /* Fire HWC */
19515fb4814Smrg    ASTFireCursor(pScrn);
19615fb4814Smrg
19715fb4814Smrg}
19815fb4814Smrg
19915fb4814Smrgstatic void
20015fb4814SmrgASTSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
20115fb4814Smrg{
20215fb4814Smrg    ASTRecPtr 	pAST = ASTPTR(pScrn);
203de78e416Smrg    ULONG fg1, bg1;
204de78e416Smrg
205de78e416Smrg    fg1 = (fg & 0x0F) | (((fg>>8) & 0x0F) << 4) | (((fg>>16) & 0x0F) << 8);
206de78e416Smrg    bg1 = (bg & 0x0F) | (((bg>>8) & 0x0F) << 4) | (((bg>>16) & 0x0F) << 8);
207de78e416Smrg
208de78e416Smrg    /* Fixed xorg bugzilla #20609, ycchen@031209 */
209de78e416Smrg    if ( (fg1 != pAST->HWCInfo.fg) || (bg1 != pAST->HWCInfo.bg) )
210de78e416Smrg    {
211de78e416Smrg    	pAST->HWCInfo.fg = fg1;
212de78e416Smrg    	pAST->HWCInfo.bg = bg1;
213de78e416Smrg        ASTLoadCursorImage(pScrn, pAST->HWCInfo.cursorpattern);
214de78e416Smrg    }
215de78e416Smrg
21615fb4814Smrg}
21715fb4814Smrg
21815fb4814Smrgstatic void
21915fb4814SmrgASTLoadCursorImage(ScrnInfoPtr pScrn, UCHAR *src)
22015fb4814Smrg{
22115fb4814Smrg    ASTRecPtr	pAST = ASTPTR(pScrn);
22215fb4814Smrg    int 	i, j, k;
22315fb4814Smrg    UCHAR 	*pjSrcAnd, *pjSrcXor, *pjDstData;
22415fb4814Smrg    ULONG   	ulTempDstAnd32[2], ulTempDstXor32[2], ulTempDstData32[2];
22515fb4814Smrg    UCHAR    	jTempSrcAnd32, jTempSrcXor32;
22615fb4814Smrg    ULONG	ulCheckSum = 0;
22715fb4814Smrg    ULONG 	ulPatternAddr;
22815fb4814Smrg
22915fb4814Smrg    /* init cursor info. */
23015fb4814Smrg    pAST->HWCInfo.cursortype = HWC_MONO;
23115fb4814Smrg    pAST->HWCInfo.width  = (USHORT) MAX_HWC_WIDTH;
23215fb4814Smrg    pAST->HWCInfo.height = (USHORT) MAX_HWC_HEIGHT;
23315fb4814Smrg    pAST->HWCInfo.offset_x = MAX_HWC_WIDTH - pAST->HWCInfo.width;
23415fb4814Smrg    pAST->HWCInfo.offset_y = MAX_HWC_HEIGHT - pAST->HWCInfo.height;
23515fb4814Smrg
236de78e416Smrg    /* copy to hwc info */
237de78e416Smrg    for (i=0; i< MAX_HWC_WIDTH*MAX_HWC_HEIGHT/4; i+=4)
238de78e416Smrg       *(ULONG *) (pAST->HWCInfo.cursorpattern + i) = *(ULONG *) (src + i);
239de78e416Smrg
24015fb4814Smrg    /* copy cursor image to cache */
24115fb4814Smrg    pjSrcXor = src;
24215fb4814Smrg    pjSrcAnd = src + (MAX_HWC_WIDTH*MAX_HWC_HEIGHT/8);
24315fb4814Smrg    pjDstData =  pAST->HWCInfo.pjHWCVirtualAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next;
24415fb4814Smrg
24515fb4814Smrg    for (j = 0; j < MAX_HWC_HEIGHT; j++)
24615fb4814Smrg    {
24715fb4814Smrg       for (i = 0; i < (MAX_HWC_WIDTH/8); i++ )
24815fb4814Smrg       {
24915fb4814Smrg       	    for (k=7; k>0; k-=2)
25015fb4814Smrg       	    {
25115fb4814Smrg                jTempSrcAnd32 = *((UCHAR *) pjSrcAnd);
252de78e416Smrg                jTempSrcXor32 = *((UCHAR *) pjSrcXor);
253de78e416Smrg                ulTempDstAnd32[0] = ((jTempSrcAnd32 >> k) & 0x01) ? 0x00008000L:0x00L;
25415fb4814Smrg                ulTempDstXor32[0] = ((jTempSrcXor32 >> k) & 0x01) ? 0x00004000L:0x00L;
25515fb4814Smrg                ulTempDstData32[0] = ((jTempSrcXor32 >> k) & 0x01) ? pAST->HWCInfo.fg:pAST->HWCInfo.bg;
25615fb4814Smrg                ulTempDstAnd32[1] = ((jTempSrcAnd32 >> (k-1)) & 0x01) ? 0x80000000L:0x00L;
25715fb4814Smrg                ulTempDstXor32[1] = ((jTempSrcXor32 >> (k-1)) & 0x01) ? 0x40000000L:0x00L;
25815fb4814Smrg                ulTempDstData32[1] = ((jTempSrcXor32 >> (k-1)) & 0x01) ? (pAST->HWCInfo.fg << 16):(pAST->HWCInfo.bg << 16);
259de78e416Smrg                /* No inverse for X Window cursor, ycchen@111808 */
260de78e416Smrg                if (ulTempDstAnd32[0])
261de78e416Smrg                    ulTempDstXor32[0] = 0;
262de78e416Smrg                if (ulTempDstAnd32[1])
263de78e416Smrg                    ulTempDstXor32[1] = 0;
26415fb4814Smrg                *((ULONG *) pjDstData) = ulTempDstAnd32[0] | ulTempDstXor32[0] | ulTempDstData32[0] | ulTempDstAnd32[1] | ulTempDstXor32[1] | ulTempDstData32[1];
26515fb4814Smrg                ulCheckSum += *((ULONG *) pjDstData);
26615fb4814Smrg                pjDstData += 4;
26715fb4814Smrg
26815fb4814Smrg            }
26915fb4814Smrg            pjSrcAnd ++;
27015fb4814Smrg            pjSrcXor ++;
27115fb4814Smrg
27215fb4814Smrg       }
27315fb4814Smrg
27415fb4814Smrg    }
27515fb4814Smrg
27615fb4814Smrg    /* Write Checksum as signature */
27715fb4814Smrg    pjDstData = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next + HWC_SIZE;
27815fb4814Smrg    *((ULONG *) pjDstData) = ulCheckSum;
27915fb4814Smrg    *((ULONG *) (pjDstData + HWC_SIGNATURE_SizeX)) = pAST->HWCInfo.width;
28015fb4814Smrg    *((ULONG *) (pjDstData + HWC_SIGNATURE_SizeY)) = pAST->HWCInfo.height;
28115fb4814Smrg    *((ULONG *) (pjDstData + HWC_SIGNATURE_HOTSPOTX)) = 0;
28215fb4814Smrg    *((ULONG *) (pjDstData + HWC_SIGNATURE_HOTSPOTY)) = 0;
28315fb4814Smrg
28415fb4814Smrg    /* set pattern offset */
28515fb4814Smrg    ulPatternAddr = ((pAST->HWCInfo.ulHWCOffsetAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next) >> 3);
28615fb4814Smrg    SetIndexReg(CRTC_PORT, 0xC8, (UCHAR) (ulPatternAddr & 0xFF));
28715fb4814Smrg    SetIndexReg(CRTC_PORT, 0xC9, (UCHAR) ((ulPatternAddr >> 8) & 0xFF));
28815fb4814Smrg    SetIndexReg(CRTC_PORT, 0xCA, (UCHAR) ((ulPatternAddr >> 16) & 0xFF));
28915fb4814Smrg
29015fb4814Smrg    /* update HWC_NUM_Next */
29115fb4814Smrg    pAST->HWCInfo.HWC_NUM_Next = (pAST->HWCInfo.HWC_NUM_Next+1) % pAST->HWCInfo.HWC_NUM;
29215fb4814Smrg
29315fb4814Smrg}
29415fb4814Smrg
29515fb4814Smrgstatic Bool
29615fb4814SmrgASTUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
29715fb4814Smrg{
298de78e416Smrg    if ( (pCurs->bits->width > MAX_HWC_WIDTH) || (pCurs->bits->height > MAX_HWC_HEIGHT) )
299de78e416Smrg        return FALSE;
300de78e416Smrg
30115fb4814Smrg    return TRUE;
30215fb4814Smrg}
30315fb4814Smrg
30415fb4814Smrgstatic void
30515fb4814SmrgASTLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs)
30615fb4814Smrg{
30715fb4814Smrg    ASTRecPtr 	pAST = ASTPTR(pScrn);
30815fb4814Smrg
30915fb4814Smrg    UCHAR	*pjDstXor, *pjSrcXor;
31015fb4814Smrg    ULONG       i, j, ulSrcWidth, ulSrcHeight;
31115fb4814Smrg    ULONG	ulPerPixelCopy, ulTwoPixelCopy;
31215fb4814Smrg    LONG        lAlphaDstDelta, lLastAlphaDstDelta;
31315fb4814Smrg    union
31415fb4814Smrg    {
31515fb4814Smrg        ULONG   ul;
31615fb4814Smrg        UCHAR   b[4];
31715fb4814Smrg    } ulSrcData32[2], ulData32;
31815fb4814Smrg    union
31915fb4814Smrg    {
32015fb4814Smrg        USHORT  us;
32115fb4814Smrg        UCHAR   b[2];
32215fb4814Smrg    } usData16;
32315fb4814Smrg    ULONG	ulCheckSum = 0;
32415fb4814Smrg    ULONG 	ulPatternAddr;
32515fb4814Smrg
32615fb4814Smrg    /* init cursor info. */
32715fb4814Smrg    pAST->HWCInfo.cursortype = HWC_COLOR;
32815fb4814Smrg    pAST->HWCInfo.width  = pCurs->bits->width;
32915fb4814Smrg    pAST->HWCInfo.height = pCurs->bits->height;
33015fb4814Smrg    pAST->HWCInfo.offset_x = MAX_HWC_WIDTH - pAST->HWCInfo.width;
33115fb4814Smrg    pAST->HWCInfo.offset_y = MAX_HWC_HEIGHT - pAST->HWCInfo.height;
33215fb4814Smrg
33315fb4814Smrg    /* copy cursor image to cache */
33415fb4814Smrg    ulSrcWidth  =  pAST->HWCInfo.width;
33515fb4814Smrg    ulSrcHeight =  pAST->HWCInfo.height;
33615fb4814Smrg
33715fb4814Smrg    lAlphaDstDelta = MAX_HWC_WIDTH << 1;
33815fb4814Smrg    lLastAlphaDstDelta = lAlphaDstDelta - (ulSrcWidth << 1);
33915fb4814Smrg
34015fb4814Smrg    pjSrcXor  = (UCHAR *) pCurs->bits->argb;;
34115fb4814Smrg    pjDstXor  = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next
34215fb4814Smrg                        + lLastAlphaDstDelta + (MAX_HWC_HEIGHT - ulSrcHeight) * lAlphaDstDelta;
34315fb4814Smrg
34415fb4814Smrg    ulPerPixelCopy =  ulSrcWidth & 1;
34515fb4814Smrg    ulTwoPixelCopy =  ulSrcWidth >> 1;
34615fb4814Smrg
34715fb4814Smrg    for (j = 0; j < ulSrcHeight; j++)
34815fb4814Smrg    {
34915fb4814Smrg
35015fb4814Smrg        for (i = 0; i < ulTwoPixelCopy; i++ )
35115fb4814Smrg        {
35215fb4814Smrg            ulSrcData32[0].ul = *((ULONG *) pjSrcXor) & 0xF0F0F0F0;
35315fb4814Smrg            ulSrcData32[1].ul = *((ULONG *) (pjSrcXor+4)) & 0xF0F0F0F0;
35415fb4814Smrg            ulData32.b[0] = ulSrcData32[0].b[1] | (ulSrcData32[0].b[0] >> 4);
35515fb4814Smrg            ulData32.b[1] = ulSrcData32[0].b[3] | (ulSrcData32[0].b[2] >> 4);
35615fb4814Smrg            ulData32.b[2] = ulSrcData32[1].b[1] | (ulSrcData32[1].b[0] >> 4);
35715fb4814Smrg            ulData32.b[3] = ulSrcData32[1].b[3] | (ulSrcData32[1].b[2] >> 4);
35815fb4814Smrg            *((ULONG *) pjDstXor) = ulData32.ul;
35915fb4814Smrg            ulCheckSum += (ULONG) ulData32.ul;
36015fb4814Smrg            pjDstXor += 4;
36115fb4814Smrg            pjSrcXor += 8;
36215fb4814Smrg        }
36315fb4814Smrg
36415fb4814Smrg        for (i = 0; i < ulPerPixelCopy; i++ )
36515fb4814Smrg        {
36615fb4814Smrg            ulSrcData32[0].ul = *((ULONG *) pjSrcXor) & 0xF0F0F0F0;
36715fb4814Smrg            usData16.b[0] = ulSrcData32[0].b[1] | (ulSrcData32[0].b[0] >> 4);
36815fb4814Smrg            usData16.b[1] = ulSrcData32[0].b[3] | (ulSrcData32[0].b[2] >> 4);
36915fb4814Smrg            *((USHORT *) pjDstXor) = usData16.us;
37015fb4814Smrg            ulCheckSum += (ULONG) usData16.us;
37115fb4814Smrg            pjDstXor += 2;
37215fb4814Smrg            pjSrcXor += 4;
37315fb4814Smrg        }
37415fb4814Smrg
37515fb4814Smrg        /* Point to next source and dest scans */
37615fb4814Smrg        pjDstXor += lLastAlphaDstDelta;
37715fb4814Smrg
37815fb4814Smrg    } /* end of for-loop */
37915fb4814Smrg
38015fb4814Smrg    /* Write Checksum as signature */
38115fb4814Smrg    pjDstXor = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next + HWC_SIZE;
38215fb4814Smrg    *((ULONG *) pjDstXor) = ulCheckSum;
38315fb4814Smrg    *((ULONG *) (pjDstXor + HWC_SIGNATURE_SizeX)) = pAST->HWCInfo.width;
38415fb4814Smrg    *((ULONG *) (pjDstXor + HWC_SIGNATURE_SizeY)) = pAST->HWCInfo.height;
38515fb4814Smrg    *((ULONG *) (pjDstXor + HWC_SIGNATURE_HOTSPOTX)) = 0;
38615fb4814Smrg    *((ULONG *) (pjDstXor + HWC_SIGNATURE_HOTSPOTY)) = 0;
38715fb4814Smrg
38815fb4814Smrg    /* set pattern offset */
38915fb4814Smrg    ulPatternAddr = ((pAST->HWCInfo.ulHWCOffsetAddr +(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next) >> 3);
39015fb4814Smrg    SetIndexReg(CRTC_PORT, 0xC8, (UCHAR) (ulPatternAddr & 0xFF));
39115fb4814Smrg    SetIndexReg(CRTC_PORT, 0xC9, (UCHAR) ((ulPatternAddr >> 8) & 0xFF));
39215fb4814Smrg    SetIndexReg(CRTC_PORT, 0xCA, (UCHAR) ((ulPatternAddr >> 16) & 0xFF));
39315fb4814Smrg
39415fb4814Smrg    /* update HWC_NUM_Next */
39515fb4814Smrg    pAST->HWCInfo.HWC_NUM_Next = (pAST->HWCInfo.HWC_NUM_Next+1) % pAST->HWCInfo.HWC_NUM;
39615fb4814Smrg
39715fb4814Smrg}
39815fb4814Smrg
39915fb4814Smrgstatic Bool
40015fb4814SmrgASTUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs)
40115fb4814Smrg{
402de78e416Smrg    if ( (pCurs->bits->width > MAX_HWC_WIDTH) || (pCurs->bits->height > MAX_HWC_HEIGHT) )
403de78e416Smrg        return FALSE;
404de78e416Smrg
40515fb4814Smrg    return TRUE;
40615fb4814Smrg}
40715fb4814Smrg
40815fb4814Smrgstatic void
40915fb4814SmrgASTFireCursor(ScrnInfoPtr pScrn)
41015fb4814Smrg{
41115fb4814Smrg    ASTRecPtr  pAST = ASTPTR(pScrn);
41215fb4814Smrg
41315fb4814Smrg    SetIndexRegMask(CRTC_PORT, 0xCB, 0xFF, 0x00);	/* dummp write to fire HWC */
41415fb4814Smrg
41515fb4814Smrg}
41615fb4814Smrg
41715fb4814Smrg#endif	/* End of HWC */
418