117a48c7cSmrg/*
217a48c7cSmrg * file: apm_dga.c
317a48c7cSmrg * ported from s3virge, ported from mga
417a48c7cSmrg *
517a48c7cSmrg */
617a48c7cSmrg
717a48c7cSmrg#ifdef HAVE_CONFIG_H
817a48c7cSmrg#include "config.h"
917a48c7cSmrg#endif
1017a48c7cSmrg
1117a48c7cSmrg#include "xf86.h"
1217a48c7cSmrg#include "xf86_OSproc.h"
1317a48c7cSmrg#include "xf86Pci.h"
1417a48c7cSmrg#include "apm.h"
1517a48c7cSmrg#include "dgaproc.h"
1617a48c7cSmrg
1717a48c7cSmrg
1817a48c7cSmrgstatic Bool ApmOpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
1917a48c7cSmrg					int *, int *, int *);
2017a48c7cSmrgstatic Bool ApmSetMode(ScrnInfoPtr, DGAModePtr);
2117a48c7cSmrgstatic int  ApmGetViewport(ScrnInfoPtr);
2217a48c7cSmrgstatic void ApmSetViewport(ScrnInfoPtr, int, int, int);
230dd80ee0Smrg#ifdef HAVE_XAA_H
2417a48c7cSmrgstatic void ApmFillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
2517a48c7cSmrgstatic void ApmBlitRect(ScrnInfoPtr, int, int, int, int, int, int);
2617a48c7cSmrgstatic void ApmBlitTransRect(ScrnInfoPtr, int, int, int, int, int, int,
2717a48c7cSmrg					unsigned long);
280dd80ee0Smrg#endif
2917a48c7cSmrgstatic void ApmSync(ScrnInfoPtr);
3017a48c7cSmrg
3117a48c7cSmrgstatic
3217a48c7cSmrgDGAFunctionRec ApmDGAFuncs = {
3317a48c7cSmrg    ApmOpenFramebuffer,
3417a48c7cSmrg    NULL,
3517a48c7cSmrg    ApmSetMode,
3617a48c7cSmrg    ApmSetViewport,
3717a48c7cSmrg    ApmGetViewport,
3817a48c7cSmrg    ApmSync,
390dd80ee0Smrg#ifdef HAVE_XAA_H
4017a48c7cSmrg    ApmFillRect,
4117a48c7cSmrg    ApmBlitRect,
4217a48c7cSmrg    ApmBlitTransRect
430dd80ee0Smrg#else
440dd80ee0Smrg    NULL, NULL, NULL
450dd80ee0Smrg#endif
4617a48c7cSmrg};
4717a48c7cSmrg
4817a48c7cSmrg/*
4917a48c7cSmrg * Placeholder
5017a48c7cSmrg */
5117a48c7cSmrgvoid
5217a48c7cSmrgApmSync(ScrnInfoPtr pScrn)
5317a48c7cSmrg{
5417a48c7cSmrg}
5517a48c7cSmrg
5617a48c7cSmrgstatic __inline__ int FindSmallestPitch(ApmPtr pApm, int Bpp, int width)
5717a48c7cSmrg{
5817a48c7cSmrg    if (width <= 640)
5917a48c7cSmrg	return 640;
6017a48c7cSmrg    else if (width <= 800)
6117a48c7cSmrg	return 800;
6217a48c7cSmrg    else if (width <= 1024)
6317a48c7cSmrg	return 1024;
6417a48c7cSmrg    else if (width <= 1152)
6517a48c7cSmrg	return 1152;
6617a48c7cSmrg    else if (width <= 1280)
6717a48c7cSmrg	return 1280;
6817a48c7cSmrg    else if (width <= 1600)
6917a48c7cSmrg	return 1600;
7017a48c7cSmrg    return (width + 7) & ~7;
7117a48c7cSmrg}
7217a48c7cSmrg
7317a48c7cSmrgstatic DGAModePtr
7417a48c7cSmrgApmSetupDGAMode(ScrnInfoPtr pScrn, DGAModePtr modes, int *num,
7517a48c7cSmrg		   int bitsPerPixel, int depth, Bool pixmap, int secondPitch,
7617a48c7cSmrg		   unsigned long red, unsigned long green, unsigned long blue,
7717a48c7cSmrg		   short visualClass)
7817a48c7cSmrg{
7917a48c7cSmrg   DisplayModePtr firstMode, pMode;
8017a48c7cSmrg   APMDECL(pScrn);
8117a48c7cSmrg   DGAModePtr mode, newmodes;
8217a48c7cSmrg   int size, pitch, Bpp = bitsPerPixel >> 3;
8317a48c7cSmrg   Bool reduced_pitch = TRUE;
8417a48c7cSmrg
8517a48c7cSmrgSECOND_PASS:
8617a48c7cSmrg
8717a48c7cSmrg   firstMode = NULL;
8817a48c7cSmrg
8917a48c7cSmrg   for (pMode = pScrn->modes; pMode != firstMode; pMode = pMode->next) {
9017a48c7cSmrg
9117a48c7cSmrg	if (!firstMode)
9217a48c7cSmrg	    firstMode = pMode;
9317a48c7cSmrg
9417a48c7cSmrg	if (reduced_pitch)
9517a48c7cSmrg	    pitch = FindSmallestPitch(pApm, Bpp, pMode->HDisplay);
9617a48c7cSmrg	else
9717a48c7cSmrg	    pitch = pMode->HDisplay;
9817a48c7cSmrg	if (!reduced_pitch && pitch == FindSmallestPitch(pApm, Bpp, pMode->HDisplay))
9917a48c7cSmrg	    continue;
10017a48c7cSmrg
10117a48c7cSmrg	size = pitch * Bpp * pMode->VDisplay;
10217a48c7cSmrg
10317a48c7cSmrg	if((!secondPitch || (pitch != secondPitch)) &&
10417a48c7cSmrg		(size <= pScrn->videoRam * 1024 - pApm->OffscreenReserved)) {
10517a48c7cSmrg
10617a48c7cSmrg	    if(secondPitch)
10717a48c7cSmrg		pitch = secondPitch;
10817a48c7cSmrg
1090dd80ee0Smrg	    if(!(newmodes = realloc(modes, (*num + 1) * sizeof(DGAModeRec))))
11017a48c7cSmrg		break;
11117a48c7cSmrg
11217a48c7cSmrg	    modes = newmodes;
11317a48c7cSmrg	    mode = modes + *num;
11417a48c7cSmrg
11517a48c7cSmrg	    mode->mode = pMode;
11617a48c7cSmrg	    mode->flags = DGA_CONCURRENT_ACCESS;
11717a48c7cSmrg
11817a48c7cSmrg	    if(pixmap)
11917a48c7cSmrg		mode->flags |= DGA_PIXMAP_AVAILABLE;
12017a48c7cSmrg	    if(!pApm->NoAccel) {
12117a48c7cSmrg		mode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
12217a48c7cSmrg		if (Bpp != 3)
12317a48c7cSmrg		    mode->flags |= DGA_BLIT_RECT_TRANS;
12417a48c7cSmrg	    }
12517a48c7cSmrg	    if(pMode->Flags & V_DBLSCAN)
12617a48c7cSmrg		mode->flags |= DGA_DOUBLESCAN;
12717a48c7cSmrg	    if(pMode->Flags & V_INTERLACE)
12817a48c7cSmrg		mode->flags |= DGA_INTERLACED;
12917a48c7cSmrg	    mode->byteOrder = pScrn->imageByteOrder;
13017a48c7cSmrg	    mode->depth = depth;
13117a48c7cSmrg	    mode->bitsPerPixel = bitsPerPixel;
13217a48c7cSmrg	    mode->red_mask = red;
13317a48c7cSmrg	    mode->green_mask = green;
13417a48c7cSmrg	    mode->blue_mask = blue;
13517a48c7cSmrg	    mode->visualClass = visualClass;
13617a48c7cSmrg	    mode->viewportWidth = pMode->HDisplay;
13717a48c7cSmrg	    mode->viewportHeight = pMode->VDisplay;
13817a48c7cSmrg	    mode->xViewportStep = (bitsPerPixel == 24) ? 4 : 1;
13917a48c7cSmrg	    mode->yViewportStep = 1;
14017a48c7cSmrg	    mode->viewportFlags = DGA_FLIP_RETRACE;
14117a48c7cSmrg	    mode->offset = 0;
14217a48c7cSmrg	    mode->address = pApm->FbBase;
14317a48c7cSmrg	    mode->bytesPerScanline = pitch * Bpp;
14417a48c7cSmrg	    mode->imageWidth = pitch;
14517a48c7cSmrg	    mode->imageHeight =  (pScrn->videoRam * 1024 -
14617a48c7cSmrg			pApm->OffscreenReserved) / mode->bytesPerScanline;
14717a48c7cSmrg	    mode->pixmapWidth = mode->imageWidth;
14817a48c7cSmrg	    mode->pixmapHeight = mode->imageHeight;
14917a48c7cSmrg	    mode->maxViewportX = mode->imageWidth - mode->viewportWidth;
15017a48c7cSmrg	   /* this might need to get clamped to some maximum */
15117a48c7cSmrg	    mode->maxViewportY = mode->imageHeight - mode->viewportHeight;
15217a48c7cSmrg
15317a48c7cSmrg	    (*num)++;
15417a48c7cSmrg	}
15517a48c7cSmrg
15617a48c7cSmrg    }
15717a48c7cSmrg
15817a48c7cSmrg    if(secondPitch) {
15917a48c7cSmrg	secondPitch = 0;
16017a48c7cSmrg	goto SECOND_PASS;
16117a48c7cSmrg    }
16217a48c7cSmrg
16317a48c7cSmrg    if (reduced_pitch) {
16417a48c7cSmrg	reduced_pitch = FALSE;
16517a48c7cSmrg	goto SECOND_PASS;
16617a48c7cSmrg    }
16717a48c7cSmrg
16817a48c7cSmrg    return modes;
16917a48c7cSmrg}
17017a48c7cSmrg
17117a48c7cSmrgBool
17217a48c7cSmrgApmDGAInit(ScreenPtr pScreen)
17317a48c7cSmrg{
1740dd80ee0Smrg   ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
17517a48c7cSmrg   APMDECL(pScrn);
17617a48c7cSmrg   DGAModePtr modes = NULL;
17717a48c7cSmrg   int num = 0;
17817a48c7cSmrg
17917a48c7cSmrg   /* 8 */
18017a48c7cSmrg   modes = ApmSetupDGAMode (pScrn, modes, &num, 8, 8,
18117a48c7cSmrg		(pScrn->bitsPerPixel != 24),
18217a48c7cSmrg		(pScrn->bitsPerPixel != 8) ? 0 : pScrn->displayWidth,
18317a48c7cSmrg		0, 0, 0, PseudoColor);
18417a48c7cSmrg
18517a48c7cSmrg   /* 15 */
18617a48c7cSmrg   modes = ApmSetupDGAMode (pScrn, modes, &num, 16, 15,
18717a48c7cSmrg		(pScrn->bitsPerPixel != 24),
18817a48c7cSmrg		(pScrn->depth != 15) ? 0 : pScrn->displayWidth,
18917a48c7cSmrg		0x7C00, 0x03E0, 0x001F, TrueColor);
19017a48c7cSmrg
19117a48c7cSmrg   modes = ApmSetupDGAMode (pScrn, modes, &num, 16, 15,
19217a48c7cSmrg		(pScrn->bitsPerPixel != 24),
19317a48c7cSmrg		(pScrn->depth != 15) ? 0 : pScrn->displayWidth,
19417a48c7cSmrg		0x7C00, 0x03E0, 0x001F, DirectColor);
19517a48c7cSmrg
19617a48c7cSmrg   /* 16 */
19717a48c7cSmrg   modes = ApmSetupDGAMode (pScrn, modes, &num, 16, 16,
19817a48c7cSmrg		(pScrn->bitsPerPixel != 24),
19917a48c7cSmrg		(pScrn->depth != 16) ? 0 : pScrn->displayWidth,
20017a48c7cSmrg		0xF800, 0x07E0, 0x001F, TrueColor);
20117a48c7cSmrg
20217a48c7cSmrg   modes = ApmSetupDGAMode (pScrn, modes, &num, 16, 16,
20317a48c7cSmrg		(pScrn->bitsPerPixel != 24),
20417a48c7cSmrg		(pScrn->depth != 16) ? 0 : pScrn->displayWidth,
20517a48c7cSmrg		0xF800, 0x07E0, 0x001F, DirectColor);
20617a48c7cSmrg
20717a48c7cSmrg   /* 24 */
20817a48c7cSmrg   modes = ApmSetupDGAMode (pScrn, modes, &num, 24, 24,
20917a48c7cSmrg		(pScrn->bitsPerPixel == 24),
21017a48c7cSmrg		(pScrn->bitsPerPixel != 24) ? 0 : pScrn->displayWidth,
21117a48c7cSmrg		0xFF0000, 0x00FF00, 0x0000FF, TrueColor);
21217a48c7cSmrg
21317a48c7cSmrg   modes = ApmSetupDGAMode (pScrn, modes, &num, 24, 24,
21417a48c7cSmrg		(pScrn->bitsPerPixel == 24),
21517a48c7cSmrg		(pScrn->bitsPerPixel != 24) ? 0 : pScrn->displayWidth,
21617a48c7cSmrg		0xFF0000, 0x00FF00, 0x0000FF, DirectColor);
21717a48c7cSmrg
21817a48c7cSmrg   /* 32 */
21917a48c7cSmrg   modes = ApmSetupDGAMode (pScrn, modes, &num, 32, 24,
22017a48c7cSmrg		(pScrn->bitsPerPixel != 24),
22117a48c7cSmrg		(pScrn->bitsPerPixel != 32) ? 0 : pScrn->displayWidth,
22217a48c7cSmrg		0xFF0000, 0x00FF00, 0x0000FF, TrueColor);
22317a48c7cSmrg
22417a48c7cSmrg   modes = ApmSetupDGAMode (pScrn, modes, &num, 32, 24,
22517a48c7cSmrg		(pScrn->bitsPerPixel != 24),
22617a48c7cSmrg		(pScrn->bitsPerPixel != 32) ? 0 : pScrn->displayWidth,
22717a48c7cSmrg		0xFF0000, 0x00FF00, 0x0000FF, DirectColor);
22817a48c7cSmrg
22917a48c7cSmrg   pApm->numDGAModes = num;
23017a48c7cSmrg   pApm->DGAModes = modes;
23117a48c7cSmrg
23217a48c7cSmrg   return DGAInit(pScreen, &ApmDGAFuncs, modes, num);
23317a48c7cSmrg}
23417a48c7cSmrg
23517a48c7cSmrg
23617a48c7cSmrgstatic Bool
23717a48c7cSmrgApmSetMode(ScrnInfoPtr pScrn, DGAModePtr pMode)
23817a48c7cSmrg{
23917a48c7cSmrg    APMDECL(pScrn);
24017a48c7cSmrg
24117a48c7cSmrg    if (!pMode) { /* restore the original mode */
24217a48c7cSmrg	if (pApm->DGAactive) {
24317a48c7cSmrg	    memcpy(&pApm->CurrentLayout, &pApm->SavedLayout,
24417a48c7cSmrg						sizeof pApm->CurrentLayout);
24517a48c7cSmrg	    pApm->DGAactive = FALSE;
24617a48c7cSmrg	}
24717a48c7cSmrg
24817a48c7cSmrg	pScrn->currentMode = pApm->CurrentLayout.pMode;
2490dd80ee0Smrg        ApmSwitchMode(SWITCH_MODE_ARGS(pScrn, pScrn->currentMode));
2500dd80ee0Smrg	ApmAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0));
25117a48c7cSmrg#if 0
25217a48c7cSmrg	if (pApm->AccelInfoRec)
25317a48c7cSmrg	    XAAInit(pScrn->pScreen, pApm->AccelInfoRec);
25417a48c7cSmrg#endif
25517a48c7cSmrg    }
25617a48c7cSmrg    else {
25717a48c7cSmrg	if (!pApm->DGAactive) {
25817a48c7cSmrg	    memcpy(&pApm->SavedLayout, &pApm->CurrentLayout,
25917a48c7cSmrg						sizeof pApm->CurrentLayout);
26017a48c7cSmrg	    pApm->DGAactive = TRUE;
26117a48c7cSmrg	}
26217a48c7cSmrg
26317a48c7cSmrg	pApm->CurrentLayout.displayWidth	= pMode->imageWidth;
26417a48c7cSmrg	pApm->CurrentLayout.displayHeight	= pMode->imageHeight;
26517a48c7cSmrg	pApm->CurrentLayout.Scanlines		= pMode->imageHeight + 1;
26617a48c7cSmrg	pApm->CurrentLayout.depth		= pMode->depth;
26717a48c7cSmrg	pApm->CurrentLayout.bitsPerPixel	= pMode->bitsPerPixel;
26817a48c7cSmrg	pApm->CurrentLayout.bytesPerScanline	= pMode->bytesPerScanline;
26917a48c7cSmrg	pApm->CurrentLayout.pMode		= pMode->mode;
27017a48c7cSmrg	if (pMode->bitsPerPixel == 24)
27117a48c7cSmrg	    pApm->CurrentLayout.mask32		= 3;
27217a48c7cSmrg	else
27317a48c7cSmrg	    pApm->CurrentLayout.mask32		= 32 / pMode->bitsPerPixel - 1;
27417a48c7cSmrg
2750dd80ee0Smrg        ApmSwitchMode(SWITCH_MODE_ARGS(pScrn, pMode->mode));
2760dd80ee0Smrg#ifdef HAVE_XAA_H
27717a48c7cSmrg	ApmSetupXAAInfo(pApm, NULL);
2780dd80ee0Smrg#endif
27917a48c7cSmrg
28017a48c7cSmrg#if 0
28117a48c7cSmrg	if (pApm->DGAXAAInfo)
28217a48c7cSmrg	    bzero(pApm->DGAXAAInfo, sizeof(*pApm->DGAXAAInfo));
28317a48c7cSmrg	else
28417a48c7cSmrg	    pApm->DGAXAAInfo = XAACreateInfoRec();
28517a48c7cSmrg	ApmSetupXAAInfo(pApm, pApm->DGAXAAInfo);
28617a48c7cSmrg	/*
28717a48c7cSmrg	 * Let's hope this won't fail, that is reinitialize XAA for this
28817a48c7cSmrg	 * setup...
28917a48c7cSmrg	 */
29017a48c7cSmrg	XAAInit(pScrn->pScreen, pApm->DGAXAAInfo);
29117a48c7cSmrg#endif
29217a48c7cSmrg    }
29317a48c7cSmrg
29417a48c7cSmrg    return TRUE;
29517a48c7cSmrg}
29617a48c7cSmrg
29717a48c7cSmrg
29817a48c7cSmrg
29917a48c7cSmrgstatic int
30017a48c7cSmrgApmGetViewport(
30117a48c7cSmrg  ScrnInfoPtr pScrn
30217a48c7cSmrg)
30317a48c7cSmrg{
30417a48c7cSmrg    return 0;
30517a48c7cSmrg}
30617a48c7cSmrg
30717a48c7cSmrgstatic void
30817a48c7cSmrgApmSetViewport(
30917a48c7cSmrg    ScrnInfoPtr pScrn,
31017a48c7cSmrg    int x, int y,
31117a48c7cSmrg    int flags
31217a48c7cSmrg)
31317a48c7cSmrg{
31417a48c7cSmrg    unsigned char tmp;
31517a48c7cSmrg
31617a48c7cSmrg    APMDECL(pScrn);
31717a48c7cSmrg
31817a48c7cSmrg    if (pApm->apmLock) {
31917a48c7cSmrg	/*
32017a48c7cSmrg	 * This is just an attempt, because Daryll is tampering with MY
32117a48c7cSmrg	 * registers.
32217a48c7cSmrg	 */
3230dd80ee0Smrg	tmp = (RDXB(0xDB) & 0xF4) |  0x0A;
3240dd80ee0Smrg	WRXB(0xDB, tmp);
3250dd80ee0Smrg	ApmWriteSeq(0x1B, 0x20);
3260dd80ee0Smrg	ApmWriteSeq(0x1C, 0x2F);
32717a48c7cSmrg	pApm->apmLock = FALSE;
32817a48c7cSmrg    }
3290dd80ee0Smrg    pScrn->AdjustFrame(ADJUST_FRAME_ARGS(pScrn, x, y));
33017a48c7cSmrg    if (pApm->VGAMap) {
33117a48c7cSmrg	/* Wait until vertical retrace is in progress. */
33217a48c7cSmrg	while (APMVGAB(0x3DA) & 0x08);
33317a48c7cSmrg	while (!(APMVGAB(0x3DA) & 0x08));
33417a48c7cSmrg    }
33517a48c7cSmrg    else {
33617a48c7cSmrg	/* Wait until vertical retrace is in progress. */
33717a48c7cSmrg	while (inb(pApm->iobase + 0x3DA) & 0x08);
33817a48c7cSmrg	while (!(inb(pApm->iobase + 0x3DA) & 0x08));
33917a48c7cSmrg    }
34017a48c7cSmrg}
34117a48c7cSmrg
3420dd80ee0Smrg#ifdef HAVE_XAA_H
34317a48c7cSmrgstatic void
34417a48c7cSmrgApmFillRect (
34517a48c7cSmrg    ScrnInfoPtr pScrn,
34617a48c7cSmrg    int x, int y, int w, int h,
34717a48c7cSmrg    unsigned long color
34817a48c7cSmrg)
34917a48c7cSmrg{
35017a48c7cSmrg    APMDECL(pScrn);
35117a48c7cSmrg
35217a48c7cSmrg    if(pApm->CurrentLayout.depth != 24) {
35317a48c7cSmrg	(*pApm->SetupForSolidFill)(pScrn, color, GXcopy, ~0);
35417a48c7cSmrg	(*pApm->SubsequentSolidFillRect)(pScrn, x, y, w, h);
35517a48c7cSmrg    }
35617a48c7cSmrg    else {
35717a48c7cSmrg	(*pApm->SetupForSolidFill24)(pScrn, color, GXcopy, ~0);
35817a48c7cSmrg	(*pApm->SubsequentSolidFillRect24)(pScrn, x, y, w, h);
35917a48c7cSmrg    }
36017a48c7cSmrg    SET_SYNC_FLAG(pApm->AccelInfoRec);
36117a48c7cSmrg}
36217a48c7cSmrg
36317a48c7cSmrgstatic void
36417a48c7cSmrgApmBlitRect(
36517a48c7cSmrg    ScrnInfoPtr pScrn,
36617a48c7cSmrg    int srcx, int srcy,
36717a48c7cSmrg    int w, int h,
36817a48c7cSmrg    int dstx, int dsty
36917a48c7cSmrg)
37017a48c7cSmrg{
37117a48c7cSmrg    APMDECL(pScrn);
37217a48c7cSmrg    int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
37317a48c7cSmrg    int ydir = (srcy < dsty) ? -1 : 1;
37417a48c7cSmrg
37517a48c7cSmrg    if(pApm->CurrentLayout.depth != 24) {
37617a48c7cSmrg	(*pApm->SetupForScreenToScreenCopy)(
37717a48c7cSmrg		pScrn, xdir, ydir, GXcopy, ~0, -1);
37817a48c7cSmrg	(*pApm->SubsequentScreenToScreenCopy)(
37917a48c7cSmrg		pScrn, srcx, srcy, dstx, dsty, w, h);
38017a48c7cSmrg    }
38117a48c7cSmrg    else {
38217a48c7cSmrg	(*pApm->SetupForScreenToScreenCopy24)(
38317a48c7cSmrg		pScrn, xdir, ydir, GXcopy, ~0, -1);
38417a48c7cSmrg	(*pApm->SubsequentScreenToScreenCopy24)(
38517a48c7cSmrg		pScrn, srcx, srcy, dstx, dsty, w, h);
38617a48c7cSmrg    }
38717a48c7cSmrg    SET_SYNC_FLAG(pApm->AccelInfoRec);
38817a48c7cSmrg}
38917a48c7cSmrg
39017a48c7cSmrgstatic void
39117a48c7cSmrgApmBlitTransRect(
39217a48c7cSmrg    ScrnInfoPtr pScrn,
39317a48c7cSmrg    int srcx, int srcy,
39417a48c7cSmrg    int w, int h,
39517a48c7cSmrg    int dstx, int dsty,
39617a48c7cSmrg    unsigned long color
39717a48c7cSmrg)
39817a48c7cSmrg{
39917a48c7cSmrg    APMDECL(pScrn);
40017a48c7cSmrg
40117a48c7cSmrg    if(pApm->AccelInfoRec) {
40217a48c7cSmrg	int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
40317a48c7cSmrg	int ydir = (srcy < dsty) ? -1 : 1;
40417a48c7cSmrg
40517a48c7cSmrg	(*pApm->AccelInfoRec->SetupForScreenToScreenCopy)(
40617a48c7cSmrg		pScrn, xdir, ydir, GXcopy, ~0, (int)color);
40717a48c7cSmrg	(*pApm->AccelInfoRec->SubsequentScreenToScreenCopy)(
40817a48c7cSmrg		pScrn, srcx, srcy, dstx, dsty, w, h);
40917a48c7cSmrg	SET_SYNC_FLAG(pApm->AccelInfoRec);
41017a48c7cSmrg    }
41117a48c7cSmrg}
4120dd80ee0Smrg#endif
41317a48c7cSmrg
41417a48c7cSmrgstatic Bool
41517a48c7cSmrgApmOpenFramebuffer(
41617a48c7cSmrg    ScrnInfoPtr pScrn,
41717a48c7cSmrg    char **name,
41817a48c7cSmrg    unsigned char **mem,
41917a48c7cSmrg    int *size,
42017a48c7cSmrg    int *offset,
42117a48c7cSmrg    int *flags
42217a48c7cSmrg)
42317a48c7cSmrg{
42417a48c7cSmrg    APMDECL(pScrn);
42517a48c7cSmrg
42617a48c7cSmrg    *name = NULL; 		/* no special device */
42717a48c7cSmrg    *mem = (unsigned char*)(pApm->LinAddress +
42817a48c7cSmrg			0*((char *)pApm->FbBase - (char *)pApm->LinMap));
42917a48c7cSmrg    *size = pScrn->videoRam << 10;
43017a48c7cSmrg    *offset = 0;
43117a48c7cSmrg    *flags = DGA_NEED_ROOT;
43217a48c7cSmrg
43317a48c7cSmrg    return TRUE;
43417a48c7cSmrg}
435