176888252Smrg#ifdef HAVE_CONFIG_H
276888252Smrg#include "config.h"
376888252Smrg#endif
476888252Smrg
576888252Smrg/* (c) Itai Nahshon */
676888252Smrg
776888252Smrg#include "xf86.h"
876888252Smrg#include "xf86_OSproc.h"
976888252Smrg#include "compiler.h"
1076888252Smrg
1176888252Smrg#include "xf86Pci.h"
1276888252Smrg
1376888252Smrg#include "vgaHW.h"
1476888252Smrg
1576888252Smrg#include "cir.h"
1676888252Smrg#define _ALP_PRIVATE_
1776888252Smrg#include "alp.h"
1876888252Smrg
1976888252Smrg#define CURSORWIDTH	pAlp->CursorWidth
2076888252Smrg#define CURSORHEIGHT	pAlp->CursorHeight
2176888252Smrg#define CURSORSIZE      (CURSORWIDTH*CURSORHEIGHT/8)
2276888252Smrg#define MAXCURSORSIZE   (64*64>>3)
2376888252Smrg
2476888252Smrgstatic void
2576888252SmrgAlpSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
2676888252Smrg{
2776888252Smrg    const AlpPtr pAlp = ALPPTR(CIRPTR(pScrn));
2876888252Smrg	vgaHWPtr hwp = VGAHWPTR(pScrn);
2976888252Smrg#ifdef ALP_DEBUG
3076888252Smrg	ErrorF("AlpSetCursorColors\n");
3176888252Smrg#endif
3276888252Smrg	hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12]|0x02);
3376888252Smrg	hwp->writeDacWriteAddr(hwp, 0x00);
3476888252Smrg	hwp->writeDacData(hwp, 0x3f & (bg >> 18));
3576888252Smrg	hwp->writeDacData(hwp, 0x3f & (bg >> 10));
3676888252Smrg	hwp->writeDacData(hwp, 0x3f & (bg >>  2));
3776888252Smrg	hwp->writeDacWriteAddr(hwp, 0x0F);
3876888252Smrg	hwp->writeDacData(hwp, 0x3F & (fg >> 18));
3976888252Smrg	hwp->writeDacData(hwp, 0x3F & (fg >> 10));
4076888252Smrg	hwp->writeDacData(hwp, 0x3F & (fg >>  2));
4176888252Smrg	hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12]);
4276888252Smrg}
4376888252Smrg
4476888252Smrgstatic void
4576888252SmrgAlpLoadSkewedCursor(CirPtr pCir, int x, int y) {
4676888252Smrg
4776888252Smrg    const AlpPtr pAlp = ALPPTR(pCir);
4876888252Smrg
4976888252Smrg    unsigned char *memx = pAlp->HWCursorBits;
5076888252Smrg        unsigned char *CursorBits = pAlp->CursorBits;
5176888252Smrg
5276888252Smrg        unsigned char mem[2*MAXCURSORSIZE];
5376888252Smrg	unsigned char *p1, *p2;
5476888252Smrg	int i, j, m, a, b;
5576888252Smrg	Bool cur64 = (CURSORWIDTH == 64);
5676888252Smrg	int shift = (cur64? 1 : 0);
5776888252Smrg
5876888252Smrg	if (x > 0) x = 0; else x = -x;
5976888252Smrg	if (y > 0) y = 0; else y = -y;
6076888252Smrg
6176888252Smrg
6276888252Smrg	a = ((y*CURSORWIDTH<<shift)+x)>>3;
6376888252Smrg	b = x & 7;
6476888252Smrg
6576888252Smrg	/* Copy the skewed mask bits */
6676888252Smrg	p1 = mem;
6776888252Smrg	p2 = CursorBits + a;
6876888252Smrg	for (i = 0; i < (CURSORSIZE << shift)-a-1; i++) {
6976888252Smrg		*p1++ = (p2[0] << b) | (p2[1] >> (8-b));
7076888252Smrg		p2++;
7176888252Smrg	}
7276888252Smrg	/* last mask byte */
7376888252Smrg	*p1++ = (p2[0] << b);
7476888252Smrg
7576888252Smrg	/* Clear to end (bottom) of mask. */
7676888252Smrg	for (i = i+1; i < (CURSORSIZE << shift); i++)
7776888252Smrg		*p1++ = 0;
7876888252Smrg
7976888252Smrg	if (!cur64) {
8076888252Smrg	    /* Now copy the cursor bits */
8176888252Smrg	    /* p1 is already right */
8276888252Smrg	    p2 = CursorBits+CURSORSIZE+a;
8376888252Smrg	    for (i = 0; i < CURSORSIZE-a-1; i++) {
8476888252Smrg		*p1++ = (p2[0] << b) | (p2[1] >> (8-b));
8576888252Smrg		p2++;
8676888252Smrg	    }
8776888252Smrg	    /* last cursor  byte */
8876888252Smrg	    *p1++ = (p2[0] << b);
8976888252Smrg	}
9076888252Smrg
9176888252Smrg	/* Clear to end (bottom) of cursor. */
9276888252Smrg	for (i = i+1; i < CURSORSIZE; i++)
9376888252Smrg		*p1++ = 0;
9476888252Smrg
9576888252Smrg	/* Clear the right unused area of the mask
9676888252Smrg	and cyrsor bits.  */
9776888252Smrg	p2 = mem + CURSORWIDTH/8 - (x>>3) - 1;
9876888252Smrg	for (i = 0; i < 2*CURSORHEIGHT; i++) {
9976888252Smrg		m = (-1)<<(x&7);
10076888252Smrg		p1 = p2;
10176888252Smrg		p2 += CURSORWIDTH/8;
10276888252Smrg		for (j = x>>3; j >= 0; j--) {
10376888252Smrg			*p1 &= m;
10476888252Smrg			m = 0;
10576888252Smrg			p1++;
10676888252Smrg		}
10776888252Smrg	}
10876888252Smrg	memcpy(memx, mem, 2*CURSORSIZE);
10976888252Smrg}
11076888252Smrg
11176888252Smrg
11276888252Smrgstatic void
11376888252SmrgAlpSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
11476888252Smrg{
11576888252Smrg	const CirPtr pCir = CIRPTR(pScrn);
11676888252Smrg	const AlpPtr pAlp = ALPPTR(pCir);
11776888252Smrg	vgaHWPtr hwp = VGAHWPTR(pScrn);
11876888252Smrg
11976888252Smrg#if 0
12076888252Smrg#ifdef ALP_DEBUG
12176888252Smrg	ErrorF("AlpSetCursorPosition %d %d\n", x, y);
12276888252Smrg#endif
12376888252Smrg#endif
12476888252Smrg
12576888252Smrg	if (x < 0 || y < 0) {
12676888252Smrg		if (x+CURSORWIDTH <= 0 || y+CURSORHEIGHT <= 0) {
12776888252Smrg			hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12] & ~0x01);
12876888252Smrg			return;
12976888252Smrg		}
13076888252Smrg		AlpLoadSkewedCursor(pCir, x, y);
13176888252Smrg		pCir->CursorIsSkewed = TRUE;
13276888252Smrg		if (x < 0) x = 0;
13376888252Smrg		if (y < 0) y = 0;
13476888252Smrg	} else if (pCir->CursorIsSkewed) {
13576888252Smrg		memcpy(pAlp->HWCursorBits, pAlp->CursorBits, 2*CURSORSIZE);
13676888252Smrg		pCir->CursorIsSkewed = FALSE;
13776888252Smrg	}
13876888252Smrg	hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12]);
13976888252Smrg	hwp->writeSeq(hwp, ((x << 5)|0x10)&0xff, x >> 3);
14076888252Smrg	hwp->writeSeq(hwp, ((y << 5)|0x11)&0xff, y >> 3);
14176888252Smrg}
14276888252Smrg
14376888252Smrgstatic void
14476888252SmrgAlpLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *bits)
14576888252Smrg{
14676888252Smrg	const AlpPtr pAlp = ALPPTR(CIRPTR(pScrn));
14776888252Smrg	vgaHWPtr hwp = VGAHWPTR(pScrn);
14876888252Smrg
14976888252Smrg#ifdef ALP_DEBUG
15076888252Smrg	ErrorF("AlpLoadCursorImage\n");
15176888252Smrg#endif
15276888252Smrg
15376888252Smrg	pAlp->CursorBits = bits;
15476888252Smrg	memcpy(pAlp->HWCursorBits, bits, 2*CURSORSIZE);
15576888252Smrg	/* this should work for both 64 and 32 bit cursors */
15676888252Smrg	pAlp->ModeReg.ExtVga[SR13] = 0x3f;
15776888252Smrg	hwp->writeSeq(hwp, 0x13, pAlp->ModeReg.ExtVga[SR13]);
15876888252Smrg}
15976888252Smrg
16076888252Smrgstatic void
16176888252SmrgAlpHideCursor(ScrnInfoPtr pScrn)
16276888252Smrg{
16376888252Smrg	AlpPtr pAlp = ALPPTR(CIRPTR(pScrn));
16476888252Smrg	vgaHWPtr hwp = VGAHWPTR(pScrn);
16576888252Smrg
16676888252Smrg#ifdef ALP_DEBUG
16776888252Smrg	ErrorF("AlpHideCursor\n");
16876888252Smrg#endif
16976888252Smrg	pAlp->ModeReg.ExtVga[SR12] &= ~0x01;
17076888252Smrg	hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12]);
17176888252Smrg}
17276888252Smrg
17376888252Smrgstatic void
17476888252SmrgAlpShowCursor(ScrnInfoPtr pScrn)
17576888252Smrg{
17676888252Smrg	AlpPtr pAlp = ALPPTR(CIRPTR(pScrn));
17776888252Smrg	vgaHWPtr hwp = VGAHWPTR(pScrn);
17876888252Smrg
17976888252Smrg#ifdef ALP_DEBUG
18076888252Smrg	ErrorF("AlpShowCursor\n");
18176888252Smrg#endif
18276888252Smrg	pAlp->ModeReg.ExtVga[SR12] |= 0x01;
18376888252Smrg	hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12]);
18476888252Smrg}
18576888252Smrg
18676888252Smrgstatic Bool
18776888252SmrgAlpUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
18876888252Smrg{
18963847c39Smrg	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
19076888252Smrg#ifdef ALP_DEBUG
19176888252Smrg	ErrorF("AlpUseHWCursor\n");
19276888252Smrg#endif
19376888252Smrg	if (pScrn->bitsPerPixel < 8)
19476888252Smrg		return FALSE;
19576888252Smrg
19676888252Smrg	return TRUE;
19776888252Smrg}
19876888252Smrg
19976888252SmrgBool
20076888252SmrgAlpHWCursorInit(ScreenPtr pScreen, int size)
20176888252Smrg{
20263847c39Smrg	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
20376888252Smrg	const CirPtr pCir = CIRPTR(pScrn);
20476888252Smrg	const AlpPtr pAlp = ALPPTR(pCir);
20576888252Smrg
20676888252Smrg	xf86CursorInfoPtr infoPtr;
20776888252Smrg
20876888252Smrg#ifdef ALP_DEBUG
20976888252Smrg	ErrorF("AlpHWCursorInit\n");
21076888252Smrg#endif
21176888252Smrg	if (!size) return FALSE;
21276888252Smrg
21376888252Smrg	infoPtr = xf86CreateCursorInfoRec();
21476888252Smrg	if (!infoPtr) return FALSE;
21576888252Smrg
21676888252Smrg	pCir->CursorInfoRec = infoPtr;
21776888252Smrg	pCir->CursorIsSkewed = FALSE;
21876888252Smrg	pAlp->CursorBits = NULL;
21976888252Smrg
22076888252Smrg	if (size == 64)
22176888252Smrg	    CURSORWIDTH = CURSORHEIGHT = 64;
22276888252Smrg	else
22376888252Smrg	    CURSORWIDTH = CURSORHEIGHT = 32;
22476888252Smrg
22576888252Smrg	pAlp->HWCursorBits = pCir->FbBase + 1024*pScrn->videoRam - 2*CURSORSIZE;
22676888252Smrg
22776888252Smrg	infoPtr->MaxWidth = CURSORWIDTH;
22876888252Smrg	infoPtr->MaxHeight = CURSORHEIGHT;
22976888252Smrg	if (CURSORWIDTH == 64)
23076888252Smrg	    infoPtr->Flags =
23176888252Smrg#if X_BYTE_ORDER == X_LITTLE_ENDIAN
23276888252Smrg		    HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
23376888252Smrg#endif
23476888252Smrg		    HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 |
23576888252Smrg		    HARDWARE_CURSOR_TRUECOLOR_AT_8BPP;
23676888252Smrg	else
23776888252Smrg		infoPtr->Flags =
23876888252Smrg#if X_BYTE_ORDER == X_LITTLE_ENDIAN
23976888252Smrg		    HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
24076888252Smrg#endif
24176888252Smrg		    HARDWARE_CURSOR_TRUECOLOR_AT_8BPP;
24276888252Smrg
24376888252Smrg	infoPtr->SetCursorColors = AlpSetCursorColors;
24476888252Smrg	infoPtr->SetCursorPosition = AlpSetCursorPosition;
24576888252Smrg	infoPtr->LoadCursorImage = AlpLoadCursorImage;
24676888252Smrg	infoPtr->HideCursor = AlpHideCursor;
24776888252Smrg	infoPtr->ShowCursor = AlpShowCursor;
24876888252Smrg	infoPtr->UseHWCursor = AlpUseHWCursor;
24976888252Smrg
25076888252Smrg#ifdef ALP_DEBUG
25176888252Smrg	ErrorF("AlpHWCursorInit before xf86InitCursor\n");
25276888252Smrg#endif
25376888252Smrg	xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Hardware cursor: %ix%i\n",
25476888252Smrg		   CURSORWIDTH,CURSORHEIGHT);
25576888252Smrg	return(xf86InitCursor(pScreen, infoPtr));
25676888252Smrg}
25776888252Smrg
25876888252Smrg
259