S3_OUT32(0x48C10, 0x6090); S3_OUT32(0x48C14, 0x70A8);
S3SAVInitialize2DEngine(){    unsigned long cobWater;    outw(vgaCRIndex, 0x0140);    outb(vgaCRIndex, 0x31);    outb(vgaCRReg, 0x0c);#define S3_IN32(off) (*(volatile unsigned int*)(((char*)s3savMmioMem)+(off)))#define S3_OUT32(off, val) (*(volatile unsigned int*)(((char*)s3savMmioMem)+(off)) = val)#define S3_OUT16(off, val) (*(volatile unsigned short*)(((char*)s3savMmioMem)+(off)) = val)    /* Setup plane masks */    S3_OUT32(0x8128, ~0); /* enable all write planes */    S3_OUT32(0x812C, ~0); /* enable all read planes */    S3_OUT16(0x8134, 0x27);    S3_OUT16(0x8136, 0x07);    if( s3vPriv.chip < S3_SAVAGE2000 )    {	/* Sav4 doc shows the smaller value in the upper DWORD. */	/* However, that's not what the NT driver does. */	if( s3vPriv.chip == S3_SAVAGE4 ) {	    cobWater = (cob.Size >> 7) * 0x10001 - 0x01400300;	}	else {	    cobWater = (cob.Size >> 2) * 0x10001 - 0x01C00EC0;	}	/* Disable BCI */	S3_OUT32(0x48C18, S3_IN32(0x48C18) & 0x3FF0);	/* Disable shadow status update */	S3_OUT32(0x48C0C, 0);	/* Setup BCI command overflow buffer */	S3_OUT32(0x48C14, (cob.Offset >> 11) | (cob.Index << 29));	/* Command overflow buffer HI/LOW watermarks */	S3_OUT32(0x48C10, cobWater);	/* Enable BCI and command overflow buffer */	S3_OUT32(0x48C18, S3_IN32(0x48C18) | 0x0C);    }    else    {	/* Disable BCI */	S3_OUT32(0x48C18, 0);	/* Disable shadow status update */	S3_OUT32(0x48A30, 0);	/* Setup BCI command overflow buffer */	S3_OUT32(0x48C18, (cob.Offset >> 7) | (cob.Index));	/* Command overflow buffer HI/LOW watermarks */	S3_OUT32(0x48C10, 0x6090);	S3_OUT32(0x48C14, 0x70A8);	/* Enable BCI and command overflow buffer */	S3_OUT32(0x48C18, S3_IN32(0x48C18) | 0x00280000 );    }    /* Use and set global bitmap descriptor. */    /* For reasons I do not fully understand yet, on the Savage4, the */    /* write to the GBD register, MM816C, does not "take" at this time. */    /* Only the low-order byte is acknowledged, resulting in an incorrect */    /* stride.  Writing the register later, after the mode switch, works */    /* correctly.  This needs to get resolved. */    s3SavedGbd = 1 | 8 | BCI_BD_BW_DISABLE;    BCI_BD_SET_BPP(s3SavedGbd, vgaBitsPerPixel);    BCI_BD_SET_STRIDE(s3SavedGbd, s3vPriv.Width);    S3SAVSetGBD();} 