[alt.sources] x11r3-suncg6-patch -- How to add CG6 support to Xsun for X11R3 comp.windows.x

marc@tekig3.PEN.TEK.COM (Marc Frajola) (12/13/89)

Archive-name: x11r3-suncg6-patch
Original-posting-by: marc@tekig3.PEN.TEK.COM (Marc Frajola)
Original-subject: Re: X11R3 on Sun 3/80 w/cgsix (+FIX)
Reposted-by: emv@math.lsa.umich.edu (Edward Vielmetti)

[This is an experimental alt.sources re-posting from the newsgroup(s)
comp.windows.x. Comments on this service to emv@math.lsa.umich.edu 
(Edward Vielmetti).]


In article <8912112257.AA00435@magic706.chron.com> sysnmc@magic706.UUCP (Matt Cohen) writes:
>      I have some new Sun 3/80's with Lego (cgsix) frame buffers in
>them that I want to run vanilla X windows on. When I compile
>and run the Sun server, it core dumps (bus error) when trying
>to set the enable bits on the hardware (file $TOP/server/ddx/sun/sunCG4C.c,
>function sunCG4CSwitch).
>      The same code compiled on a 4/280 runs perfectly on a
>SparcStation 1 with a cgsix, so I know it _can_ work. The file
><sundev/cg6reg.h> (on the 3/80, it's different on the SS1) says that
>the base address of the board is different on Sun3's from Sun4's.
>I assume this is the problem.
>      The question is: does anyone have a patch or other fix
>to the X source to make this work? Thanks in advance.

    I too had X bomb when I compiled and ran it on a Sun-4/330 with a
Lego (cgsix) accelerator. The symptoms were a bunch of memory parity
errors (bogus) which eventually caused a watchdog timeout. I contacted
my local Sun office, and after about a week and a half, I got a reply
with a sunCG6.c file and instructions on how to patch sunInit.c to use
the new code.

    The only problem with this patch is that it still seems to come up
thinking I have a cg4 by default, and so I must supply extra flags to
xinit; I must use 'xinit -- -dev /dev/cgsix0' to bring up the server
properly. In order to do this, you must go to /dev and do a MAKEDEV
cgsix. At least your 3/80 core dumps instead of halting like I did on
one of our 4/330s. :-) :-)

    Following is a shar with the CG6 and a READ-ME file; you'll need to
extract this in $TIP/server/ddx/sun and follow the instructions in
READ-ME. I haven't spent much time figuring out if I can re-order the
table entries specified in sunInit.c to make it check for a CG6 before
matching it up to a CG4 (I'd really like it if the default was cg6
since all of our 4/330s have CG6's in them). If anybody else out there
has a more elegant fix and/or can make cg6 the default, PLEASE let me
know...

    My apologies if this is too specific to be posted, but I know that
graphics accelerators are popping up everywhere, and I figure it will
be of use to several people out there...

    Any replies should be directed to marc@tekig3.LEN.TEK.COM, though
start on Friday (December 15), my new address will be
marc@tekig3.PEN.TEK.COM (domain name changes during the day Friday). If
that address bounces, then try marc@escargot.UUCP...

    I'd also like to thank Sun Microsystems for providing this on my
request... Does Sun want to post an official patch or is this it?

...Marc...
--
Marc Frajola, Tektronix Inc., Beaverton, OR
Phone: (503) 627-4340 (Tek) or (503) 643-5203 (Home)
UUCP: ..!tektronix.TEK.COM!tekig3.LEN.TEK.COM!marc (Tek - Lab Scopes)
      ..!tektronix.TEK.COM!tessi.UUCP!escargot!marc (Home System e-mail)

---------- Cut here for CG6.shar ---------------------------------------
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	READ-ME
#	sunCG6.c
# This archive created: Tue Oct  3 11:23:14 1989
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f 'READ-ME'
then
	echo shar: "will not over-write existing file 'READ-ME'"
else
cat << \SHAR_EOF > 'READ-ME'

	How to add CG6 support to Xsun for X11R3.

modify sunInit.c :

add the following to the list of extern's at the top of the file.

	extern Bool sunCG6Probe();


modify the sunFbDataRec declaration by adding an entry for the cg6 as
follows:

	#ifdef ZOIDS
	sunFbDataRec sunFbData[] = {
	    sunBW2Probe,  	"/dev/bwtwo0",	    neverProbed,	0, 0,
	    sunCG2CProbe,  	"/dev/cgtwo0",	    neverProbed,	0, 0,
	    sunCG3CProbe,  	"/dev/cgthree0",    neverProbed,	0, 0,
	    sunCG4CProbe,  	"/dev/cgfour0",	    neverProbed,	0, 0,
	    sunCG6Probe,  	"/dev/cgsix0",	    neverProbed,	0, 0,
	};
	#else  ZOIDS
	sunFbDataRec sunFbData[] = {
	    sunBW2Probe,  	"/dev/bwtwo0",	    neverProbed,
	    sunCG2CProbe,  	"/dev/cgtwo0",	    neverProbed,
	    sunCG3CProbe,  	"/dev/cgthree0",    neverProbed,
	    sunCG4CProbe,  	"/dev/cgfour0",	    neverProbed,
	    sunCG6Probe,  	"/dev/cgsix0",	    neverProbed,
	};
	#endif ZOIDS



modify Imakefile:

	Add sunCG6.c and sunCG6.o


To start Xsun you MUST specify -dev /dev/cgsix0 or else the auto
config code seems to think that it is a cg4.





					Tom Jarmolowski
					jarmolowski%esdsdf.decnet@ge-crd.arpa

SHAR_EOF
fi
if test -f 'sunCG6.c'
then
	echo shar: "will not over-write existing file 'sunCG6.c'"
else
cat << \SHAR_EOF > 'sunCG6.c'
/*-
 * sunCG6C.c --
 *	Functions to support the sun CG6 board as a memory frame buffer.
 */

/****************************************************************/
/* Modified from  sunCG4C.c for X11R3 by Tom Jarmolowski	*/
/****************************************************************/

/************************************************************
Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.

                    All Rights Reserved

Permission  to  use,  copy,  modify,  and  distribute   this
software  and  its documentation for any purpose and without
fee is hereby granted, provided that the above copyright no-
tice  appear  in all copies and that both that copyright no-
tice and this permission notice appear in  supporting  docu-
mentation,  and  that the names of Sun or MIT not be used in
advertising or publicity pertaining to distribution  of  the
software  without specific prior written permission. Sun and
M.I.T. make no representations about the suitability of this
software for any purpose. It is provided "as is" without any
express or implied warranty.

SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO  THIS  SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE  LI-
ABLE  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.

********************************************************/

#ifndef	lint
static char sccsid[] = "@(#)sunCG6C.c	1.4 6/1/87 Copyright 1987 Sun Micro";
#endif

#include    "sun.h"

#include    <sys/mman.h>
#include    <pixrect/memreg.h>
#include    <sundev/cg4reg.h>
#include    <sundev/cg6reg.h>
#include    "colormap.h"
#include    "colormapst.h"
#include    "resource.h"
#include    <struct.h>

#define	CG6_HEIGHT	900
#define	CG6_WIDTH	1152

typedef struct cg6c {
	u_char cpixel[CG6_HEIGHT][CG6_WIDTH];	/* byte-per-pixel memory */
} CG6, CG6Rec, *CG6Ptr;


#define CG6_IMAGE(fb)	    ((caddr_t)(&(fb)->cpixel))
#define CG6_IMAGEOFF	    ((off_t)0x0)
#define CG6_IMAGELEN	    (((CG6_HEIGHT*CG6_WIDTH + 8191)/8192)*8192)

static CG6Ptr CG6fb = NULL;

/* XXX - next line means only one CG6 - fix this */
static ColormapPtr sunCG6InstalledMap;

extern int TellLostMap(), TellGainedMap();

static void
sunCG6UpdateColormap(pScreen, index, count, rmap, gmap, bmap)
    ScreenPtr	pScreen;
    int		index, count;
    u_char	*rmap, *gmap, *bmap;
{
    struct fbcmap sunCmap;

    sunCmap.index = index;
    sunCmap.count = count;
    sunCmap.red = &rmap[index];
    sunCmap.green = &gmap[index];
    sunCmap.blue = &bmap[index];

#ifdef SUN_WINDOWS
    if (sunUseSunWindows()) {
	static Pixwin *pw = 0;

	if (! pw) {
	    if ( ! (pw = pw_open(windowFd)) )
		FatalError( "sunCG6UpdateColormap: pw_open failed\n" );
	    pw_setcmsname(pw, "X.V11");
	}
	pw_putcolormap(
	    pw, index, count, &rmap[index], &gmap[index], &bmap[index]);
    }
#endif SUN_WINDOWS

    if (ioctl(sunFbs[pScreen->myNum].fd, FBIOPUTCMAP, &sunCmap) < 0) {
	perror("sunCG6UpdateColormap");
	FatalError( "sunCG6UpdateColormap: FBIOPUTCMAP failed\n" );
    }
}

/*-
 *-----------------------------------------------------------------------
 * sunCG6SaveScreen --
 *	Preserve the color screen by turning on or off the video
 *
 * Results:
 *	None.
 *
 * Side Effects:
 *	Video state is switched
 *
 *-----------------------------------------------------------------------
 */
static Bool
sunCG6SaveScreen (pScreen, on)
    ScreenPtr	  pScreen;
    Bool    	  on;
{
    int		state = on;

    if (on != SCREEN_SAVER_ON) {
	SetTimeSinceLastInputEvent();
	state = 1;
    } else {
	state = 0;
    }

    (void) ioctl(sunFbs[pScreen->myNum].fd, FBIOSVIDEO, &state);
    return( TRUE );
}

/*-
 *-----------------------------------------------------------------------
 * sunCG6CloseScreen --
 *	called to ensure video is enabled when server exits.
 *
 * Results:
 *	Screen is unsaved.
 *
 * Side Effects:
 *	None
 *
 *-----------------------------------------------------------------------
 */
/*ARGSUSED*/
static Bool
sunCG6CloseScreen(i, pScreen)
    int		i;
    ScreenPtr	pScreen;
{
    sunCG6InstalledMap = NULL;
    return (pScreen->SaveScreen(pScreen, SCREEN_SAVER_OFF));
}

/*-
 *-----------------------------------------------------------------------
 * sunCG6InstallColormap --
 *	Install given colormap.
 *
 * Results:
 *	None
 *
 * Side Effects:
 *	Existing map is uninstalled.
 *	All clients requesting ColormapNotify are notified
 *
 *-----------------------------------------------------------------------
 */
static void
sunCG6InstallColormap(cmap)
    ColormapPtr	cmap;
{
    register int i;
    register Entry *pent = cmap->red;
    u_char	  rmap[256], gmap[256], bmap[256];

    if (cmap == sunCG6InstalledMap)
	return;
    if (sunCG6InstalledMap)
	WalkTree(sunCG6InstalledMap->pScreen, TellLostMap,
		 (char *) &(sunCG6InstalledMap->mid));
    for (i = 0; i < cmap->pVisual->ColormapEntries; i++) {
	if (pent->fShared) {
	    rmap[i] = pent->co.shco.red->color >> 8;
	    gmap[i] = pent->co.shco.green->color >> 8;
	    bmap[i] = pent->co.shco.blue->color >> 8;
	}
	else {
	    rmap[i] = pent->co.local.red >> 8;
	    gmap[i] = pent->co.local.green >> 8;
	    bmap[i] = pent->co.local.blue >> 8;
	}
	pent++;
    }
    sunCG6InstalledMap = cmap;
    sunCG6UpdateColormap(cmap->pScreen, 0, 256, rmap, gmap, bmap);
    WalkTree(cmap->pScreen, TellGainedMap, (char *) &(cmap->mid));
}

/*-
 *-----------------------------------------------------------------------
 * sunCG6UninstallColormap --
 *	Uninstall given colormap.
 *
 * Results:
 *	None
 *
 * Side Effects:
 *	default map is installed
 *	All clients requesting ColormapNotify are notified
 *
 *-----------------------------------------------------------------------
 */
static void
sunCG6UninstallColormap(cmap)
    ColormapPtr	cmap;
{
    if (cmap == sunCG6InstalledMap) {
	Colormap defMapID = cmap->pScreen->defColormap;

	if (cmap->mid != defMapID) {
	    ColormapPtr defMap = (ColormapPtr) LookupID(defMapID, RT_COLORMAP, RC_CORE);

	    if (defMap)
		sunCG6InstallColormap(defMap);
	    else
	        ErrorF("sunCG6: Can't find default colormap\n");
	}
    }
}

/*-
 *-----------------------------------------------------------------------
 * sunCG6ListInstalledColormaps --
 *	Fills in the list with the IDs of the installed maps
 *
 * Results:
 *	Returns the number of IDs in the list
 *
 * Side Effects:
 *	None
 *
 *-----------------------------------------------------------------------
 */
/*ARGSUSED*/
static int
sunCG6ListInstalledColormaps(pScreen, pCmapList)
    ScreenPtr	pScreen;
    Colormap	*pCmapList;
{
    *pCmapList = sunCG6InstalledMap->mid;
    return (1);
}


/*-
 *-----------------------------------------------------------------------
 * sunCG6StoreColors --
 *	Sets the pixels in pdefs into the specified map.
 *
 * Results:
 *	None
 *
 * Side Effects:
 *	None
 *
 *-----------------------------------------------------------------------
 */
static void
sunCG6StoreColors(pmap, ndef, pdefs)
    ColormapPtr	pmap;
    int		ndef;
    xColorItem	*pdefs;
{
    switch (pmap->class) {
    case PseudoColor:
	if (pmap == sunCG6InstalledMap) {
	    /* We only have a single colormap */
	    u_char	rmap[256], gmap[256], bmap[256];

	    while (ndef--) {
		register unsigned index = pdefs->pixel&0xff;

		/* PUTCMAP assumes colors to be assigned start at 0 */
		rmap[index] = (pdefs->red) >> 8;
		gmap[index] = (pdefs->green) >> 8;
		bmap[index] = (pdefs->blue) >> 8;
	 	sunCG6UpdateColormap(pmap->pScreen,
				      index, 1, rmap, gmap, bmap);
		pdefs++;
	    }
	}
	break;
    case DirectColor:
    default:
	ErrorF("sunCG6StoreColors: bad class %d\n", pmap->class);
	break;
    }
}

/*-
 *-----------------------------------------------------------------------
 * sunCG6ResolvePseudoColor --
 *	Adjust specified RGB values to closest values hardware can do.
 *
 * Results:
 *	Args are modified.
 *
 * Side Effects:
 *	None
 *
 *-----------------------------------------------------------------------
 */
/*ARGSUSED*/
static void
sunCG6ResolvePseudoColor(pRed, pGreen, pBlue, pVisual)
    CARD16	*pRed, *pGreen, *pBlue;
    VisualPtr	pVisual;
{
    *pRed &= 0xff00;
    *pGreen &= 0xff00;
    *pBlue &= 0xff00;
}

/*-
 *-----------------------------------------------------------------------
 * sunCG6Init --
 *	Attempt to find and initialize a cg6 framebuffer used as mono
 *
 * Results:
 *	TRUE if everything went ok. FALSE if not.
 *
 * Side Effects:
 *	Most of the elements of the ScreenRec are filled in. Memory is
 *	allocated for the frame buffer and the buffer is mapped. The
 *	video is enabled for the frame buffer...
 *
 *-----------------------------------------------------------------------
 */
/*ARGSUSED*/
static Bool
sunCG6Init (index, pScreen, argc, argv)
    int	    	  index;    	/* The index of pScreen in the ScreenInfo */
    ScreenPtr	  pScreen;  	/* The Screen to initialize */
    int	    	  argc;	    	/* The number of the Server's arguments. */
    char    	  **argv;   	/* The arguments themselves. Don't change! */
{
    CARD16	zero = 0, ones = ~0;

    if (!cfbScreenInit (index, pScreen, CG6fb->cpixel,	
			    sunFbs[index].info.fb_width,
			    sunFbs[index].info.fb_height, 90))
	return (FALSE);

    pScreen->SaveScreen    =            sunCG6SaveScreen;
    pScreen->RecolorCursor = 	    	sunRecolorCursor;

#ifndef STATIC_COLOR
    pScreen->InstallColormap = sunCG6InstallColormap;
    pScreen->UninstallColormap = sunCG6UninstallColormap;
    pScreen->ListInstalledColormaps = sunCG6ListInstalledColormaps;
    pScreen->StoreColors = sunCG6StoreColors;
    pScreen->ResolveColor = sunCG6ResolvePseudoColor;
#endif

    {
	ColormapPtr cmap = (ColormapPtr)LookupID(pScreen->defColormap, RT_COLORMAP, RC_CORE);

	if (!cmap)
	    FatalError("Can't find default colormap\n");
	if (AllocColor(cmap, &ones, &ones, &ones, &(pScreen->whitePixel), 0)
	    || AllocColor(cmap, &zero, &zero, &zero, &(pScreen->blackPixel), 0))
		FatalError("Can't alloc black & white pixels in cfbScreeninit\n");
	sunCG6InstallColormap(cmap);
    }


    sunCG6SaveScreen( pScreen, SCREEN_SAVER_FORCER );
    sunScreenInit (pScreen);
    return (TRUE);
}

/*-
 *--------------------------------------------------------------
 * sunCG6Switch --
 *      Enable or disable color plane 
 *
 * Results:
 *      Color plane enabled for select =0, disabled otherwise.
 *
 *--------------------------------------------------------------
 */
static void
sunCG6Switch ()
{
}

/*-
 *-----------------------------------------------------------------------
 * sunCG6Probe --
 *	Attempt to find and initialize a cg6 framebuffer used as mono
 *
 * Results:
 *	TRUE if everything went ok. FALSE if not.
 *
 * Side Effects:
 *	Memory is allocated for the frame buffer and the buffer is mapped.
 *
 *-----------------------------------------------------------------------
 */
Bool
sunCG6Probe (pScreenInfo, index, fbNum, argc, argv)
    ScreenInfo	  *pScreenInfo;	/* The screenInfo struct */
    int	    	  index;    	/* The index of pScreen in the ScreenInfo */
    int	    	  fbNum;    	/* Index into the sunFbData array */
    int	    	  argc;	    	/* The number of the Server's arguments. */
    char    	  **argv;   	/* The arguments themselves. Don't change! */
{
    int         i, oldNumScreens;

    if (sunFbData[fbNum].probeStatus == probedAndFailed) {
	return FALSE;
    }

    if (sunFbData[fbNum].probeStatus == neverProbed) {
	int         fd;
	struct fbtype fbType;

	if ((fd = sunOpenFrameBuffer(FBTYPE_SUN4COLOR, &fbType, index, fbNum,
				     argc, argv)) < 0) {
	    sunFbData[fbNum].probeStatus = probedAndFailed;
	    return FALSE;
	}

#ifdef	_MAP_NEW

	CG6fb = (CG6Ptr) 0;

#else	_MAP_NEW


	CG6fb = (CG6Ptr) valloc(CG6_IMAGELEN);
	if (CG6fb == (CG6Ptr) NULL) {
	    ErrorF("Could not allocate room for frame buffer.\n");
	    sunFbData[fbNum].probeStatus = probedAndFailed;
	    return FALSE;
	}

#endif	_MAP_NEW

	CG6fb = (CG6Ptr) mmap((caddr_t) CG6fb,
		 CG6_IMAGELEN,
		 PROT_READ | PROT_WRITE,
		 MAP_SHARED | _MAP_NEW, fd, CG6_VADDR_COLOR);


	if ((CG6fb == (CG6Ptr) -1)  || (CG6fb == (CG6Ptr) 0)) {
	    Error("Mapping cg6c");
	    sunFbData[fbNum].probeStatus = probedAndFailed;
	    (void) close(fd);
	    return FALSE;
	}


	sunFbs[index].fd = fd;
	sunFbs[index].info = fbType;
	sunFbs[index].fb = (pointer) CG6fb;
        sunFbs[index].EnterLeave = sunCG6Switch;
	sunFbData[fbNum].probeStatus = probedAndSucceeded;

    }

    /*
     * If we've ever successfully probed this device, do the following. 
     */

    oldNumScreens = pScreenInfo->numScreens;
    i = AddScreen(sunCG6Init, argc, argv);
    pScreenInfo->screen[index].CloseScreen = sunCG6CloseScreen;
    /* Now set the enable plane for color */
    if (index == 0) sunCG6Switch (&(pScreenInfo->screen[0]), 0);

    return (i > oldNumScreens);
}
SHAR_EOF
fi
exit 0
#	End of shell archive