344 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			344 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			C
		
	
	
	
/*
 | 
						|
 * Id: smidraw.c,v 1.1 1999/11/02 03:54:47 keithp Exp $
 | 
						|
 *
 | 
						|
 * Copyright © 1999 Keith Packard
 | 
						|
 *
 | 
						|
 * Permission to use, copy, modify, distribute, and sell this software and its
 | 
						|
 * documentation for any purpose is hereby granted without fee, provided that
 | 
						|
 * the above copyright notice appear in all copies and that both that
 | 
						|
 * copyright notice and this permission notice appear in supporting
 | 
						|
 * documentation, and that the name of Keith Packard not be used in
 | 
						|
 * advertising or publicity pertaining to distribution of the software without
 | 
						|
 * specific, written prior permission.  Keith Packard makes no
 | 
						|
 * representations about the suitability of this software for any purpose.  It
 | 
						|
 * is provided "as is" without express or implied warranty.
 | 
						|
 *
 | 
						|
 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | 
						|
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | 
						|
 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 | 
						|
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 | 
						|
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 | 
						|
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | 
						|
 * PERFORMANCE OF THIS SOFTWARE.
 | 
						|
 */
 | 
						|
/* $XFree86: xc/programs/Xserver/hw/kdrive/smi/smidraw.c,v 1.7 2001/07/24 19:06:03 keithp Exp $ */
 | 
						|
 | 
						|
#ifdef HAVE_CONFIG_H
 | 
						|
#include <kdrive-config.h>
 | 
						|
#endif
 | 
						|
#include "smi.h"
 | 
						|
#include "smidraw.h"
 | 
						|
 | 
						|
#include	<X11/Xmd.h>
 | 
						|
#include	"gcstruct.h"
 | 
						|
#include	"scrnintstr.h"
 | 
						|
#include	"pixmapstr.h"
 | 
						|
#include	"regionstr.h"
 | 
						|
#include	"mistruct.h"
 | 
						|
#include	"dixfontstr.h"
 | 
						|
#include	"fb.h"
 | 
						|
#include	"migc.h"
 | 
						|
#include	"miline.h"
 | 
						|
#include	"picturestr.h"
 | 
						|
#include	"kaa.h"
 | 
						|
 | 
						|
CARD8 smiBltRop[16] = {
 | 
						|
    /* GXclear      */      0x00,         /* 0 */
 | 
						|
    /* GXand        */      0x88,         /* src AND dst */
 | 
						|
    /* GXandReverse */      0x44,         /* src AND NOT dst */
 | 
						|
    /* GXcopy       */      0xcc,         /* src */
 | 
						|
    /* GXandInverted*/      0x22,         /* NOT src AND dst */
 | 
						|
    /* GXnoop       */      0xaa,         /* dst */
 | 
						|
    /* GXxor        */      0x66,         /* src XOR dst */
 | 
						|
    /* GXor         */      0xee,         /* src OR dst */
 | 
						|
    /* GXnor        */      0x11,         /* NOT src AND NOT dst */
 | 
						|
    /* GXequiv      */      0x99,         /* NOT src XOR dst */
 | 
						|
    /* GXinvert     */      0x55,         /* NOT dst */
 | 
						|
    /* GXorReverse  */      0xdd,         /* src OR NOT dst */
 | 
						|
    /* GXcopyInverted*/     0x33,         /* NOT src */
 | 
						|
    /* GXorInverted */      0xbb,         /* NOT src OR dst */
 | 
						|
    /* GXnand       */      0x77,         /* NOT src OR NOT dst */
 | 
						|
    /* GXset        */      0xff,         /* 1 */
 | 
						|
};
 | 
						|
 | 
						|
CARD8 smiSolidRop[16] = {
 | 
						|
    /* GXclear      */      0x00,         /* 0 */
 | 
						|
    /* GXand        */      0xa0,         /* src AND dst */
 | 
						|
    /* GXandReverse */      0x50,         /* src AND NOT dst */
 | 
						|
    /* GXcopy       */      0xf0,         /* src */
 | 
						|
    /* GXandInverted*/      0x0a,         /* NOT src AND dst */
 | 
						|
    /* GXnoop       */      0xaa,         /* dst */
 | 
						|
    /* GXxor        */      0x5a,         /* src XOR dst */
 | 
						|
    /* GXor         */      0xfa,         /* src OR dst */
 | 
						|
    /* GXnor        */      0x05,         /* NOT src AND NOT dst */
 | 
						|
    /* GXequiv      */      0xa5,         /* NOT src XOR dst */
 | 
						|
    /* GXinvert     */      0x55,         /* NOT dst */
 | 
						|
    /* GXorReverse  */      0xf5,         /* src OR NOT dst */
 | 
						|
    /* GXcopyInverted*/     0x0f,         /* NOT src */
 | 
						|
    /* GXorInverted */      0xaf,         /* NOT src OR dst */
 | 
						|
    /* GXnand       */      0x5f,         /* NOT src OR NOT dst */
 | 
						|
    /* GXset        */      0xff,         /* 1 */
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
#define GET_STATUS(smic) smiGetIndex (smic, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x16)
 | 
						|
 | 
						|
#define ENGINE_IDLE_EMPTY(smic) ((GET_STATUS(smic) & 0x18) == 0x10)
 | 
						|
#define FIFO_EMPTY(smic)	((GET_STATUS(smic) & 0x10) == 0x10)
 | 
						|
 | 
						|
#define MAX_FIFO    16
 | 
						|
 | 
						|
void
 | 
						|
smiWaitAvail(SmiCardInfo *smic, int n)
 | 
						|
{
 | 
						|
    if (smic->avail < n)
 | 
						|
    {
 | 
						|
	while (!FIFO_EMPTY (smic))
 | 
						|
	    ;
 | 
						|
	smic->avail = MAX_FIFO;
 | 
						|
    }
 | 
						|
    smic->avail -= n;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
smiWaitIdle (SmiCardInfo *smic)
 | 
						|
{
 | 
						|
    while (!ENGINE_IDLE_EMPTY (smic))
 | 
						|
	;
 | 
						|
    smic->avail = MAX_FIFO;
 | 
						|
}
 | 
						|
 | 
						|
static SmiCardInfo	*smic;
 | 
						|
static SmiScreenInfo	*smis;
 | 
						|
static DPR		*dpr;
 | 
						|
static CARD32		accel_cmd;
 | 
						|
 | 
						|
static Bool
 | 
						|
smiSetup (ScreenPtr pScreen, int wait)
 | 
						|
{
 | 
						|
    KdScreenPriv(pScreen);
 | 
						|
 | 
						|
    smis = getSmiScreenInfo (pScreenPriv);
 | 
						|
    smic = getSmiCardInfo(pScreenPriv);
 | 
						|
    dpr = smic->dpr;
 | 
						|
    
 | 
						|
    if (!dpr)
 | 
						|
	return FALSE;
 | 
						|
    
 | 
						|
    /* enable DPR/VPR registers */
 | 
						|
    smiSetIndex (smic, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, 
 | 
						|
		 smis->dpr_vpr_enable);
 | 
						|
    
 | 
						|
    smiWaitAvail (smic, wait + 9);
 | 
						|
    dpr->src_stride = (smis->stride << 16) | smis->stride;
 | 
						|
    dpr->data_format = smis->data_format;
 | 
						|
    dpr->mask1 = 0xffffffff;
 | 
						|
    dpr->mask2 = 0xffffffff;
 | 
						|
    dpr->dst_stride = (smis->stride << 16) | smis->stride;
 | 
						|
    dpr->unknown_40 = 0x0;
 | 
						|
    dpr->unknown_44 = 0x0;
 | 
						|
    dpr->scissors_ul = 0x0;
 | 
						|
    dpr->scissors_lr = SMI_XY(4095,4095);
 | 
						|
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
smiWaitMarker (ScreenPtr pScreen, int marker)
 | 
						|
{
 | 
						|
    KdScreenPriv(pScreen);
 | 
						|
    smic = getSmiCardInfo(pScreenPriv);
 | 
						|
    
 | 
						|
    smiWaitIdle (smic);
 | 
						|
}
 | 
						|
 | 
						|
static Bool
 | 
						|
smiPrepareSolid (PixmapPtr    pPixmap,
 | 
						|
		 int		alu,
 | 
						|
		 Pixel		pm,
 | 
						|
		 Pixel		fg)
 | 
						|
{
 | 
						|
    if (~pm & FbFullMask(pPixmap->drawable.depth))
 | 
						|
	return FALSE;
 | 
						|
    
 | 
						|
    if (!smiSetup (pPixmap->drawable.pScreen, 3))
 | 
						|
	return FALSE;
 | 
						|
    
 | 
						|
    accel_cmd = smiSolidRop[alu] | SMI_BITBLT | SMI_START_ENGINE;
 | 
						|
    dpr->fg = fg;
 | 
						|
    dpr->mask3 = 0xffffffff;
 | 
						|
    dpr->mask4 = 0xffffffff;
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
smiSolid (int x1, int y1, int x2, int y2)
 | 
						|
{
 | 
						|
    smiWaitAvail(smic,3);
 | 
						|
    dpr->dst_xy = SMI_XY(x1,y1);
 | 
						|
    dpr->dst_wh = SMI_XY(x2-x1,y2-y1);
 | 
						|
    dpr->accel_cmd = accel_cmd; 
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
smiDoneSolid (void)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
static int copyDx;
 | 
						|
static int copyDy;
 | 
						|
 | 
						|
static Bool
 | 
						|
smiPrepareCopy (PixmapPtr	pSrcPixmap,
 | 
						|
		PixmapPtr	pDstPixmap,
 | 
						|
		int		dx,
 | 
						|
		int		dy,
 | 
						|
		int		alu,
 | 
						|
		Pixel		pm)
 | 
						|
{
 | 
						|
    if (~pm & FbFullMask(pSrcPixmap->drawable.depth))
 | 
						|
	return FALSE;
 | 
						|
    
 | 
						|
    if (!smiSetup (pSrcPixmap->drawable.pScreen, 0))
 | 
						|
	return FALSE;
 | 
						|
    
 | 
						|
    accel_cmd = smiBltRop[alu] | SMI_BITBLT | SMI_START_ENGINE;
 | 
						|
    
 | 
						|
    copyDx = dx;
 | 
						|
    copyDy = dy;
 | 
						|
    if (dy < 0 || (dy == 0 && dx < 0))
 | 
						|
	accel_cmd |= SMI_RIGHT_TO_LEFT;
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
smiCopy (int srcX,
 | 
						|
	    int srcY,
 | 
						|
	    int dstX,
 | 
						|
	    int dstY,
 | 
						|
	    int w,
 | 
						|
	    int h)
 | 
						|
{
 | 
						|
    if (accel_cmd & SMI_RIGHT_TO_LEFT)
 | 
						|
    {
 | 
						|
	srcX += w - 1;
 | 
						|
	dstX += w - 1;
 | 
						|
	srcY += h - 1;
 | 
						|
	dstY += h - 1;
 | 
						|
    }
 | 
						|
    smiWaitAvail (smic, 4);
 | 
						|
    dpr->src_xy = SMI_XY (srcX, srcY);
 | 
						|
    dpr->dst_xy = SMI_XY (dstX, dstY);
 | 
						|
    dpr->dst_wh = SMI_XY (w, h);
 | 
						|
    dpr->accel_cmd = accel_cmd;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
smiDoneCopy (void)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
Bool
 | 
						|
smiDrawInit (ScreenPtr pScreen)
 | 
						|
{
 | 
						|
    KdScreenPriv(pScreen);
 | 
						|
    smiCardInfo (pScreenPriv);
 | 
						|
    
 | 
						|
    ENTER ();
 | 
						|
    if (pScreenPriv->screen->fb[0].depth == 4)
 | 
						|
    {
 | 
						|
	LEAVE ();
 | 
						|
	return FALSE;
 | 
						|
    }
 | 
						|
    
 | 
						|
    if (!smic->dpr)
 | 
						|
    {
 | 
						|
	LEAVE ();
 | 
						|
	return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    memset(&smis->kaa, 0, sizeof(KaaScreenInfoRec));
 | 
						|
    smis->kaa.PrepareSolid	= smiPrepareSolid;
 | 
						|
    smis->kaa.Solid		= smiSolid;
 | 
						|
    smis->kaa.DoneSolid		= smiDoneSolid;
 | 
						|
    smis->kaa.PrepareCopy	= smiPrepareCopy;
 | 
						|
    smis->kaa.Copy		= smiCopy;
 | 
						|
    smis->kaa.DoneCopy		= smiDoneCopy;
 | 
						|
    smis->kaa.waitMarker	= smiWaitMarker;
 | 
						|
 | 
						|
    if (!kaaDrawInit (pScreen, &smis->kaa))
 | 
						|
    {
 | 
						|
	LEAVE ();
 | 
						|
	return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    LEAVE ();
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
smiDrawEnable (ScreenPtr pScreen)
 | 
						|
{
 | 
						|
    KdScreenPriv(pScreen);
 | 
						|
    int i;
 | 
						|
    static const int xyAddress[] = { 320, 400, 512, 640, 800, 1024, 1280, 1600, 2048 };
 | 
						|
    
 | 
						|
    ENTER ();
 | 
						|
    smis = getSmiScreenInfo (pScreenPriv);
 | 
						|
    smic = getSmiCardInfo(pScreenPriv);
 | 
						|
    dpr = smic->dpr;
 | 
						|
    
 | 
						|
    smis->stride = pScreenPriv->screen->fb[0].byteStride;
 | 
						|
    smis->dpr_vpr_enable = smiGetIndex (smic, VGA_SEQ_INDEX, 
 | 
						|
					VGA_SEQ_DATA, 0x21) & ~0x03;
 | 
						|
    
 | 
						|
    switch (pScreenPriv->screen->fb[0].depth) {
 | 
						|
    case 8:
 | 
						|
	smis->data_format = 0x00000000;
 | 
						|
	break;
 | 
						|
    case 15:
 | 
						|
    case 16:
 | 
						|
	smis->data_format = 0x00100000;
 | 
						|
	smis->stride >>= 1;
 | 
						|
	break;
 | 
						|
    case 24:
 | 
						|
	smis->data_format = 0x00300000;
 | 
						|
	break;
 | 
						|
    case 32:
 | 
						|
	smis->data_format = 0x00200000;
 | 
						|
	smis->stride >>= 2;
 | 
						|
	break;
 | 
						|
    }
 | 
						|
    for (i = 0; i < sizeof(xyAddress) / sizeof(xyAddress[0]); i++)
 | 
						|
    {
 | 
						|
	if (xyAddress[i] == pScreenPriv->screen->fb[0].pixelStride)
 | 
						|
	{
 | 
						|
	    smis->data_format |= i << 16;
 | 
						|
	    break;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    
 | 
						|
    smiSetup (pScreen, 0);
 | 
						|
    kaaMarkSync (pScreen);
 | 
						|
    LEAVE ();
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
smiDrawDisable (ScreenPtr pScreen)
 | 
						|
{
 | 
						|
    ENTER ();
 | 
						|
    smic = 0;
 | 
						|
    smis = 0;
 | 
						|
    dpr = 0;
 | 
						|
    accel_cmd = 0;
 | 
						|
    LEAVE ();
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
smiDrawFini (ScreenPtr pScreen)
 | 
						|
{
 | 
						|
    ENTER ();
 | 
						|
    LEAVE ();
 | 
						|
}
 |