diff -ruN XFree86-3.3.5/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/Imakefile XFree86-3.3.3.1/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/Imakefile --- XFree86-3.3.5/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/Imakefile Wed Jun 23 08:37:21 1999 +++ XFree86-3.3.3.1/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/Imakefile Sat Oct 24 03:54:44 1998 @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/Imakefile,v 1.1.2.9 1999/06/23 12:37:21 hohndel Exp $ +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/Imakefile,v 1.1.2.8 1998/10/22 04:31:05 hohndel Exp $ XCOMM XCOMM This is an Imakefile for the cyrix driver. XCOMM @@ -6,10 +6,10 @@ #include SRCS = cyrix_driver.c cyrix_accel.c cyrix_cursor.c cyrix_cmap.c cyrix_bank.s \ - cyrix_asm.s gxrender.c + cyrix_asm.s OBJS = cyrix_driver.o cyrix_accel.o cyrix_cursor.o cyrix_cmap.o cyrix_bank.o \ - cyrix_asm.o gxrender.o + cyrix_asm.o DEFINES = -DPSZ=8 @@ -61,7 +61,6 @@ InstallLinkKitNonExecFile(cyrix_driver.c,$(LINKKITDIR)/drivers/vga256/cyrix) InstallLinkKitNonExecFile(cyrix_bank.s,$(LINKKITDIR)/drivers/vga256/cyrix) InstallLinkKitNonExecFile(cyrix_asm.s,$(LINKKITDIR)/drivers/vga256/cyrix) -InstallLinkKitNonExecFile(gxrender.c,$(LINKKITDIR)/drivers/vga256/cyrix) InstallLinkKitNonExecFile(Imakefile,$(LINKKITDIR)/drivers/vga256/cyrix) XCOMM @@ -82,4 +81,3 @@ XCOMM Install Link Kit Non Exec File(Imakefile,$(LINKKITDIR)/drivers/vga16/cyrix) DependTarget() - diff -ruN XFree86-3.3.5/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix.h XFree86-3.3.3.1/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix.h --- XFree86-3.3.5/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix.h Tue Dec 22 02:49:58 1998 +++ XFree86-3.3.3.1/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix.h Fri Nov 6 11:41:51 1998 @@ -1,5 +1,5 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix.h,v 1.1.2.6 1998/12/22 07:49:58 hohndel Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix.h,v 1.1.2.5 1998/11/06 09:47:02 hohndel Exp $ */ /* this code is partly based on the MediaGX sources from the GGI project based on CYRIX example code (gxvideo.c) and included with CYRIX and @@ -88,10 +88,9 @@ #define CYRIXsetVectorMode() \ GX_REG(GP_VECTOR_MODE) = (vectorMode) -#define IfDest(rop, planemask, val) \ - (( (((rop) & 0x5) ^ (((rop) & 0xA) >> 1)) \ - || (~((planemask) & 0xFF)) \ - ) ? (val) : 0) +#define IfDest(xrop, val) ((((xrop) & 0x5) ^ (((xrop) & 0xA) >> 1)) ? (val) : 0) + + /* Generic MediaGX hardware register and value definitions */ diff -ruN XFree86-3.3.5/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix_accel.c XFree86-3.3.3.1/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix_accel.c --- XFree86-3.3.5/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix_accel.c Wed Jun 23 08:37:21 1999 +++ XFree86-3.3.3.1/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix_accel.c Fri Nov 6 11:41:51 1998 @@ -1,7 +1,6 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix_accel.c,v 1.1.2.6 1999/06/23 12:37:21 hohndel Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix_accel.c,v 1.1.2.3 1998/11/06 09:47:04 hohndel Exp $ */ /* - * Copyright 1999 by Brian Falardeau. * Copyright 1998 by Annius Groenink, Amsterdam. * * Permission to use, copy, modify, distribute, and sell this software and its @@ -33,6 +32,7 @@ #include "cyrix.h" #include "miline.h" + /* size of color expand source area (embedded in frame buffer) */ #define CYRIXexpandSize 32768 @@ -41,64 +41,17 @@ upper nybble inverted X raster operation (bits 0 - 3 correspond to bits 3 - 0 and 7 - 4 in Windows style ROP). In some routines, the role of source and pattern is inverted. */ - -/* The following ROPs only use pattern and destination data. */ -/* They are used when the planemask specifies all planes (no mask). */ - -static const int windowsROPpat[16] = { - 0x00, /* GXclear = 0 */ - 0xA0, /* GXand = pat AND dst */ - 0x50, /* GXandReverse = pat AND NOT dst */ - 0xF0, /* GXcopy = pat */ - 0x0A, /* GXandInverted = NOT pat AND dst */ - 0xAA, /* GXnoop = dst */ - 0x5A, /* GXxor = pat XOR dst */ - 0xFA, /* GXor = pat OR dst */ - 0x05, /* GXnor = NOT pat AND NOT dst */ - 0xA5, /* GXequiv = NOT pat XOR dst */ - 0x55, /* GXinvert = NOT dst */ - 0xF5, /* GXorReverse = pat OR NOT dst */ - 0x0F, /* GXcopyInverted = NOT pat */ - 0xAF, /* GXorInverted = NOT pat OR dst */ - 0x5F, /* GXnand = NOT pat OR NOT dst */ - 0xFF, /* GXset = 1 */ -}; - -/* The following ROPs use source data to specify a planemask. */ -/* If the planemask (src) is one, then the result is the appropriate */ -/* combination of pattern and destination data. If the planemask (src) */ -/* is zero, then the result is always just destination data. */ - -static const int windowsROPsrcMask[16] = { - 0x22, /* GXclear => 0 if src = 1, dst if src = 0 */ - 0xA2, /* GXand = pat AND dst if src = 1, dst if src = 0 */ - 0x62, /* GXandReverse = pat AND NOT dst if src = 1, dst if src = 0 */ - 0xE2, /* GXcopy = pat if src = 1, dst if src = 0 */ - 0x2A, /* GXandInverted = NOT pat AND dst if src = 1, dst if src = 0 */ - 0xAA, /* GXnoop = dst if src = 1, dst if src = 0 */ - 0x6A, /* GXxor = pat XOR dst if src = 1, dst if src = 0 */ - 0xEA, /* GXor = pat OR dst if src = 1, dst if src = 0 */ - 0x26, /* GXnor = NOT pat AND NOT dst if src = 1, dst if src = 0 */ - 0xA6, /* GXequiv = NOT pat XOR dst if src = 1, dst if src = 0 */ - 0x66, /* GXinvert = NOT dst if src = 1, dst if src = 0 */ - 0xE6, /* GXorReverse = pat OR NOT dst if src = 1, dst if src = 0 */ - 0x2E, /* GXcopyInverted = NOT pat if src = 1, dst if src = 0 */ - 0xAE, /* GXorInverted = NOT pat OR dst if src = 1, dst if src = 0 */ - 0x6E, /* GXnand = NOT pat OR NOT dst if src = 1, dst if src = 0 */ - 0xEE, /* GXset = 1 if src = 1, dst if src = 0 */ -}; - -/* The following ROPs use pattern data to specify a planemask. */ -/* If the planemask (pat) is one, then the result is the appropriate */ -/* combination of source and destination data. If the planemask (pat) */ -/* is zero, then the result is always just destination data. */ - static const int windowsROPpatMask[16] = { 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA }; +static const int windowsROPsrcMask[16] = { 0x22, 0xA2, 0x62, 0xE2, + 0x2A, 0xAA, 0x6A, 0xEA, + 0x26, 0xA6, 0x66, 0xE6, + 0x2E, 0xAE, 0x6E, 0xEE }; +static int bltBufWidth; static int blitMode; static int vectorMode; @@ -106,85 +59,25 @@ static int copyXdir; static int setBlitModeOnSync = 0; -/* STATIC VARIABLES FOR THIS FILE */ -/* Used to maintain state between setup and rendering calls. */ - -static int CYRIXsavedROP; -static int CYRIXtransparent; -static int CYRIXtransColor; -static int CYRIXstartMonoExpand = 0; - -static unsigned short CYRIXsaveX, CYRIXsaveY, CYRIXsaveW, CYRIXsaveH; /* Forward declaration of functions used in the driver */ - void CYRIXAccelSync(); void CYRIXAccelInit(); void CYRIXSetupForFillRectSolid(); void CYRIXSubsequentFillRectSolid(); -void CYRIXSetupFor8x8PatternColorExpand(); -void CYRIXSubsequent8x8PatternColorExpand(); void CYRIXSetupForScreenToScreenCopy(); void CYRIXSubsequentScreenToScreenCopy(); - void CYRIXSubsequentBresenhamLine(); +void CYRIXSetupFor8x8PatternColorExpand(); +void CYRIXSubsequent8x8PatternColorExpand(); void CYRIXSetupForCPUToScreenColorExpand(); void CYRIXSubsequentCPUToScreenColorExpand(); -/* Routines in GXRENDER.C */ - -void gxr_initialize(unsigned char *regptr, unsigned short bpp, - unsigned short BB0base, unsigned short BB1base, - unsigned short BBwidthPixels); - -void gxr_wait_until_idle(void); - -void gxr_load_solid_source(unsigned short color); - -void gxr_load_mono_source(unsigned short bgcolor, unsigned short fgcolor, - unsigned short transparent); - -void gxr_load_solid_pattern(unsigned short color); - -void gxr_load_mono_pattern(unsigned short bgcolor, unsigned short fgcolor, - unsigned long data0, unsigned long data1, unsigned char transparency); - -void gxr_load_raster_operation(unsigned char rop); - -void gxr_pattern_fill(unsigned short x, unsigned short y, - unsigned short width, unsigned short height); - -void gxr_screen_to_screen_blt(unsigned short srcx, unsigned short srcy, - unsigned short dstx, unsigned short dsty, unsigned short width, - unsigned short height); - -void gxr_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy, - unsigned short dstx, unsigned short dsty, unsigned short width, - unsigned short height, unsigned short color); - -void gxr_text_glyph(unsigned short srcx, unsigned short srcy, - unsigned short dstx, unsigned short dsty, unsigned short width, - unsigned short height, unsigned char *data, unsigned short pitch); - -void gxr_bresenham_line(unsigned short x, unsigned short y, - unsigned short length, unsigned short initerr, - unsigned short axialerr, unsigned short diagerr, - unsigned short flags); - -/* -//--------------------------------------------------------------------------- -// CYRIXAccelInit -// -// This routine hooks the acceleration routines and sets appropriate flags. -//--------------------------------------------------------------------------- -*/ +/* Acceleration init function, sets up pointers to our accelerated functions */ void CYRIXAccelInit() -{ - int bltBufWidth; - - /* General acceleration flags */ +{ /* General acceleration flags */ xf86AccelInfoRec.Flags = PIXMAP_CACHE | BACKGROUND_OPERATIONS | HARDWARE_PATTERN_SCREEN_ORIGIN @@ -245,344 +138,232 @@ /* calculate the pixel width of a blit buffer for convenience */ bltBufWidth = CYRIXbltBufSize / (vgaBitsPerPixel / 8); +} - /* pass parameters to GXRENDER.C file */ - gxr_initialize((unsigned char *) GXregisters, - (unsigned short) vgaBitsPerPixel, - (unsigned short) CYRIXbltBuf0Address, - (unsigned short) CYRIXbltBuf1Address, - (unsigned short) bltBufWidth); -} +/* set colors - called through access macros in cyrix.h */ +static __inline__ void CYRIXsetColors01(reg, col0, col1) +int reg; +int col0; +int col1; +{ if (vgaBitsPerPixel == 16) + GX_REG(reg) = ((col1 & 0xFFFF) << 16) | (col0 & 0xFFFF); + else + { col0 &= 0xFF; + col1 &= 0xFF; + GX_REG(reg) = (col1 << 24) | (col1 << 16) | (col0 << 8) | col0; +} } -/* -//--------------------------------------------------------------------------- -// CYRIXAccelSync -// -// This routine is called before accessing the frame buffer directly to -// make sure that the graphics pipeline is idle. It is also called after -// loading the monochrome data into BB0 for bitmap to screen BLTs. -//--------------------------------------------------------------------------- -*/ +/* The generic Sync() function that waits for everything to + be completed (e.g. before writing to the frame buffer + directly). */ void CYRIXAccelSync() -{ - /* CHECK IF END TO CPU TO SCREEN EXPAND BLT */ - - if (CYRIXstartMonoExpand) - { - /* START CPU TO SCREEN EXPAND BLT */ - /* Data has already been loaded into BB0, so use NULL pointer. */ - - /* this is formally incorrect: XAA may use both BB0 and BB1 - for the text source bitmap, so READ_DST_FB1 should not be - used. So far, this problem has not manifested itself in - practice. */ - - CYRIXstartMonoExpand = 0; - gxr_text_glyph(0, 0, CYRIXsaveX, CYRIXsaveY, CYRIXsaveW, - CYRIXsaveH, 0, 0); +{ if (setBlitModeOnSync) + { setBlitModeOnSync = 0; + CYRIXsetupSync(); + CYRIXsetBlitMode(); } - - /* WAIT UNTIL IDLE */ - - gxr_wait_until_idle(); + while (GX_REG(GP_BLIT_STATUS) & + (BS_BLIT_BUSY|BS_PIPELINE_BUSY|BS_BLIT_PENDING)); } -/* -//--------------------------------------------------------------------------- -// CYRIXSetupForFillRectSolid -// -// This routine is called to setup the solid pattern color for future -// rectangular fills or vectors. -//--------------------------------------------------------------------------- -*/ - +/* Solid rectangles */ void CYRIXSetupForFillRectSolid(color, rop, planemask) int color, rop; unsigned int planemask; -{ - /* LOAD THE SOLID PATTERN COLOR */ - - gxr_load_solid_pattern((unsigned short) color); - - /* CHECK IF PLANEMASK IS NOT USED (ALL PLANES ENABLED) */ - - if (planemask == (unsigned int) -1) - { - /* use normal pattern ROPs if all planes are enabled */ - - gxr_load_raster_operation(windowsROPpat[rop & 0x0F]); - } - else - { - /* select ROP that uses planemask in src data */ - - gxr_load_solid_source((unsigned short) planemask); - gxr_load_raster_operation(windowsROPsrcMask[rop & 0x0F]); - } +{ CYRIXsetupSync(); + CYRIXsetSourceColors01(color, color); + CYRIXsetPatColors01(planemask, 0); + CYRIXsetPatMode(rop, RM_PAT_DISABLE); + blitMode = BM_READ_SRC_NONE | BM_WRITE_FB | BM_SOURCE_EXPAND + | IfDest(rop, BM_READ_DST_FB0); + vectorMode = IfDest(rop, VM_READ_DST_FB); } -/* -//--------------------------------------------------------------------------- -// CYRIXSubsequentFillRectSolid -// -// This routine is called to fill a rectangular region using the previously -// specified solid pattern and raster operation. -// -// Sample application uses: -// - Window backgrounds. -// - x11perf: rectangle tests (-rect500). -// - x11perf: fill trapezoid tests (-trap100). -// - x11perf: horizontal line segments (-hseg500). -//--------------------------------------------------------------------------- -*/ void CYRIXSubsequentFillRectSolid(x, y, w, h) int x, y, w, h; -{ - /* call routine to fill rectangular region */ - - gxr_pattern_fill((unsigned short) x, (unsigned short) y, - (unsigned short) w, (unsigned short) h); -} - -/* -//--------------------------------------------------------------------------- -// CYRIXSetupFor8x8PatternColorExpand -// -// This routine is called to setup the monochrome pattern (8x8) and raster -// operation for future rectangular fills. -//--------------------------------------------------------------------------- -*/ - -void CYRIXSetupFor8x8PatternColorExpand(patternx, patterny, bg, fg, rop, planemask) -int patternx, patterny; -int bg, fg, rop; -unsigned int planemask; -{ int trans = (bg == -1); - - /* LOAD PATTERN COLORS AND DATA */ - - gxr_load_mono_pattern((unsigned short) bg, (unsigned short) fg, - (unsigned long) patternx, (unsigned long) patterny, - (unsigned char) trans); - - /* CHECK IF PLANEMASK IS NOT USED (ALL PLANES ENABLED) */ - - if (planemask == (unsigned int) -1) - { - /* use normal pattern ROPs if all planes are enabled */ - - gxr_load_raster_operation(windowsROPpat[rop & 0x0F]); - } - else - { - /* select ROP that uses planemask in src data */ - - gxr_load_solid_source((unsigned short) planemask); - gxr_load_raster_operation(windowsROPsrcMask[rop & 0x0F]); +{ /* divide the operation into columns if required; use twice the + blit buffer width because buffer 0 will overflow into buffer 1 */ + while (w > 2 * bltBufWidth) + { CYRIXSubsequentFillRectSolid(x, y, 2 * bltBufWidth, h); + x += 2 * bltBufWidth; + w -= 2 * bltBufWidth; } + CYRIXsetupSync(); + CYRIXsetDstXY(x, y); + CYRIXsetWH(w, h); + CYRIXsetBlitMode(); } -/* -//--------------------------------------------------------------------------- -// CYRIXSubsequent8x8PatternColorExpand -// -// This routine is called to fill a rectangular region using the previously -// specified monochrome pattern (8x8) and raster operation. -// -// Sample application uses: -// - Patterned desktops -// - x11perf: stippled rectangle tests (-srect500). -// - x11perf: opaque stippled rectangle tests (-osrect500). -//--------------------------------------------------------------------------- -*/ - -void CYRIXSubsequent8x8PatternColorExpand(patternx, patterny, x, y, w, h) -int patternx, patterny; -int x, y, w, h; -{ - /* call routine to fill rectangular region */ - - gxr_pattern_fill((unsigned short) x, (unsigned short) y, - (unsigned short) w, (unsigned short) h); -} - -/* -//--------------------------------------------------------------------------- -// CYRIXSetupForScreenToScreenCopy -// -// This routine is called to setup the planemask and raster operation -// for future screen to screen BLTs. -//--------------------------------------------------------------------------- -*/ +/* Screen to screen copies */ void CYRIXSetupForScreenToScreenCopy(xdir, ydir, rop, planemask, transparency_color) int xdir, ydir; int rop; unsigned int planemask; int transparency_color; -{ - /* LOAD PLANEMASK INTO PATTERN DATA */ +{ CYRIXsetupSync(); + CYRIXsetPatColors01(planemask, 0); - gxr_load_solid_pattern((unsigned short) planemask); - - /* SET RASTER OPERATION FOR USING PATTERN AS PLANE MASK */ + if (transparency_color == -1) + { CYRIXsetPatMode(rop, RM_PAT_DISABLE); + transMode = 0; + } + else + { CYRIXsetPatModeTrans(RM_PAT_DISABLE); + transMode = 1; - gxr_load_raster_operation(windowsROPpatMask[rop & 0x0F]); + /* fill blit buffer 1 with the transparency color */ + if (vgaBitsPerPixel == 16) + { int k = CYRIXbltBufSize / 4; + CARD32 val = (transparency_color << 16) | + transparency_color; + volatile CARD32* buf = &(GX_REG(CYRIXbltBuf1Address)); + + while (--k >= 0) buf[k] = val; + } + else + memset(GXregisters + CYRIXbltBuf1Address, + transparency_color, CYRIXbltBufSize); + } - /* SAVE TRANSPARENCY FLAG */ + blitMode = BM_READ_SRC_FB | BM_WRITE_FB | BM_SOURCE_COLOR + | (transMode ? IfDest(rop, BM_READ_DST_FB1) : BM_READ_DST_NONE) + | (ydir < 0 ? BM_REVERSE_Y : 0); - CYRIXtransparent = (transparency_color == -1) ? 0 : 1; - CYRIXtransColor = transparency_color; + copyXdir = xdir; } -/* -//--------------------------------------------------------------------------- -// CYRIXSubsequentScreenToScreenCopy -// -// This routine is called to perform a screen to screen BLT using the -// previously specified planemask, raster operation, and transparency flag. -// -// Sample application uses (non-transparent): -// - Moving windows. -// - x11perf: scroll tests (-scroll500). -// - x11perf: copy from window to window (-copywinwin500). -// -// No application found using transparency. -//--------------------------------------------------------------------------- -*/ - void CYRIXSubsequentScreenToScreenCopy(x1, y1, x2, y2, w, h) int x1, y1, x2, y2, w, h; -{ - if (CYRIXtransparent) - { - /* CALL ROUTINE FOR TRANSPARENT SCREEN TO SCREEN BLT */ - /* Should only be called for the "copy" raster operation. */ - - gxr_screen_to_screen_xblt( - (unsigned short) x1, (unsigned short) y1, - (unsigned short) x2, (unsigned short) y2, - (unsigned short) w, (unsigned short) h, - (unsigned short) CYRIXtransColor); +{ int up = (blitMode & BM_REVERSE_Y); + + /* divide the operation into columns when necessary */ + if (copyXdir < 0) + { int x_offset = w - bltBufWidth; + + while (x_offset > 0) + { CYRIXSubsequentScreenToScreenCopy(x1 + x_offset, y1, + x2 + x_offset, y2, + bltBufWidth, h); + x_offset -= bltBufWidth; + w -= bltBufWidth; + } } + else while (w > bltBufWidth) + { CYRIXSubsequentScreenToScreenCopy(x1, y1, x2, y2, + bltBufWidth, h); + x1 += bltBufWidth; + x2 += bltBufWidth; + w -= bltBufWidth; } - else - { - /* CALL ROUTINE FOR NORMAL SCREEN TO SCREEN BLT */ - gxr_screen_to_screen_blt( - (unsigned short) x1, (unsigned short) y1, - (unsigned short) x2, (unsigned short) y2, - (unsigned short) w, (unsigned short) h); + CYRIXsetupSync(); + CYRIXsetSrcXY(x1, (up ? (y1 + h - 1) : y1)); + CYRIXsetDstXY(x2, (up ? (y2 + h - 1) : y2)); + + /* in transparent mode, one line reads the transparency color + into a processor-internal register, and the remaining lines + can be done in a single second pass */ + if (transMode) + { blitMode |= BM_READ_DST_BB1; + CYRIXsetWH(w, 1); + CYRIXsetBlitMode(); + h--; + if (!h) return; + if (up) { y1--; y2--; } + else { y1++; y2++; } + CYRIXsetupSync(); + blitMode &= ~(BM_READ_DST_BB1); } + CYRIXsetWH(w, h); + CYRIXsetBlitMode(); } -/* -//--------------------------------------------------------------------------- -// CYRIXSubsequentBresenhamLine -// -// This routine is called to render a vector using the specified Bresenham -// parameters. -// -// Sample application uses: -// - Window outlines on window move. -// - x11perf: line segments (-seg500). -//--------------------------------------------------------------------------- -*/ +/* Bresenham lines */ void CYRIXSubsequentBresenhamLine(x1, y1, octant, err, e1, e2, length) int x1, y1, octant, err, e1, e2, length; -{ - unsigned short flags; - - /* DETERMINE YMAJOR AND DIRECTION FLAGS */ - - if (octant & YMAJOR) - { flags = VM_Y_MAJOR; - if (!(octant & XDECREASING)) flags |= VM_MINOR_INC; - if (!(octant & YDECREASING)) flags |= VM_MAJOR_INC; +{ if (octant & YMAJOR) + { vectorMode = (vectorMode & VM_READ_DST_FB) | VM_Y_MAJOR; + if (!(octant & XDECREASING)) vectorMode |= VM_MINOR_INC; + if (!(octant & YDECREASING)) vectorMode |= VM_MAJOR_INC; } else - { flags = VM_X_MAJOR; - if (!(octant & XDECREASING)) flags |= VM_MAJOR_INC; - if (!(octant & YDECREASING)) flags |= VM_MINOR_INC; + { vectorMode = (vectorMode & VM_READ_DST_FB) | VM_X_MAJOR; + if (!(octant & XDECREASING)) vectorMode |= VM_MAJOR_INC; + if (!(octant & YDECREASING)) vectorMode |= VM_MINOR_INC; } - /* CALL ROUTINE TO DRAW VECTOR */ - - gxr_bresenham_line((unsigned short) x1, (unsigned short) y1, - (unsigned short) length, (unsigned short) err, - (unsigned short) e1, (unsigned short) e2, (unsigned short) flags); + CYRIXsetupSync(); + CYRIXsetDstXY(x1, y1); + CYRIXsetWH(length, (err & 0xFFFF)); + CYRIXsetSrcXY((e1 & 0xFFFF), (e2 & 0xFFFF)); + CYRIXsetVectorMode(); } -/* -//--------------------------------------------------------------------------- -// CYRIXSetupForCPUToScreenColorExpand -// -// This routine is called to setup the planemask, colors, and raster -// operation for future monocrome bitmap to screen BLTs. -//--------------------------------------------------------------------------- -*/ -void CYRIXSetupForCPUToScreenColorExpand(bg, fg, rop, planemask) +/* 8x8 pattern color expand */ +void CYRIXSetupFor8x8PatternColorExpand(patternx, patterny, bg, fg, rop, planemask) +int patternx, patterny; int bg, fg, rop; unsigned int planemask; { int trans = (bg == -1); - /* LOAD SOURCE COLORS */ + CYRIXsetupSync(); + CYRIXsetSourceColors01(planemask, planemask); + CYRIXsetPatColors01(trans ? 0 : bg, fg); + CYRIXsetPatData(patternx, patterny); + CYRIXsetPatModeX(rop, RM_PAT_MONO | (trans ? RM_PAT_TRANSPARENT : 0)); - gxr_load_mono_source((unsigned short) bg, (unsigned short) fg, - (unsigned short) trans); + blitMode = BM_READ_SRC_NONE | BM_WRITE_FB | BM_SOURCE_EXPAND + | (trans ? IfDest(rop, BM_READ_DST_FB0) : BM_READ_DST_NONE); +} - /* LOAD PLANEMASK INTO PATTERN DATA */ +void CYRIXSubsequent8x8PatternColorExpand(patternx, patterny, x, y, w, h) +int patternx, patterny; +int x, y, w, h; +{ CYRIXSubsequentFillRectSolid(x, y, w, h); +} - gxr_load_solid_pattern((unsigned short) planemask); - - /* SET RASTER OPERATION FOR USING PATTERN AS PLANE MASK */ - gxr_load_raster_operation(windowsROPpatMask[rop & 0x0F]); -} +/* CPU-to-screen color expansion */ +void CYRIXSetupForCPUToScreenColorExpand(bg, fg, rop, planemask) +int bg, fg, rop; +unsigned int planemask; +{ int trans = (bg == -1); -/* -//--------------------------------------------------------------------------- -// CYRIXSubsequentCPUToScreenColorExpand -// -// This routine is called to render expanded monocrome bitmap data to the -// screen using the previously specified colors and raster operation. Since -// the server loads the monochrome data into BB0, not the driver, this -// routine just sets a flag and saves the parameters to use when the server -// is done loading the data and calls the CYRIXAccelSync function. -// -// Sample application uses: -// - Text in windows. -// - x11perf: text (-ftext, -f8text, -f9text, ...). -//--------------------------------------------------------------------------- -*/ + CYRIXsetupSync(); + CYRIXsetSourceColors01(trans ? 0 : bg, fg); + CYRIXsetPatColors01(planemask, 0); + + CYRIXsetPatMode(rop, RM_PAT_DISABLE | (trans ? RM_SRC_TRANSPARENT : 0)); + + /* this is formally incorrect: XAA may use both BB0 and BB1 + for the text source bitmap, so READ_DST_FB1 should not be + used. So far, this problem has not manifested itself in + practice. */ + blitMode = BM_READ_SRC_BB0 | BM_WRITE_FB | BM_SOURCE_EXPAND + | (trans ? IfDest(rop, BM_READ_DST_FB1) : BM_READ_DST_NONE); +} void CYRIXSubsequentCPUToScreenColorExpand(x, y, w, h, skipleft) int x, y, w, h; int skipleft; -{ - CYRIXstartMonoExpand = 1; - CYRIXsaveX = x; - CYRIXsaveY = y; - CYRIXsaveW = w; - CYRIXsaveH = h; - - /* WAIT UNTIL IDLE BEFORE ALLOWING WRITES TO BLT BUFFERS */ - /* Server will load the monochrome data into BB0 after this. */ +{ CYRIXsetupSync(); + CYRIXsetSrcXY(0, 0); + CYRIXsetDstXY(x, y); + CYRIXsetWH(w, h); - gxr_wait_until_idle(); + CYRIXAccelSync(); + setBlitModeOnSync = 1; } - -/* END OF FILE */ diff -ruN XFree86-3.3.5/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix_driver.c XFree86-3.3.3.1/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix_driver.c --- XFree86-3.3.5/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix_driver.c Wed Jun 23 08:37:22 1999 +++ XFree86-3.3.3.1/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix_driver.c Fri Nov 6 11:41:51 1998 @@ -1,12 +1,9 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix_driver.c,v 1.1.2.7 1999/06/23 12:37:22 hohndel Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix_driver.c,v 1.1.2.6 1998/11/06 09:47:08 hohndel Exp $ */ /* - * Copyright 1999 by Brian Falardeau * Copyright 1998 by Annius V. Groenink (A.V.Groenink@zfc.nl, avg@cwi.nl), * Dirk H. Hohndel (hohndel@suse.de), * Portions: the GGI project & confidential CYRIX databooks. * - * Substitute Brian Falardeau into a copy of the following legal jargon... - * * 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 @@ -25,17 +22,13 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ +/* $XConsortium: $ */ /*************************************************************************/ /* Log for the cyrix driver source as a whole - May 1999, Brian Falardeau: - - Fixed interaction with SoftVGA for setting 2K pitch at 1280x1024. - - Added CRTC tables for 60 Hz and 75 Hz modes. - - Removed enabling display compression directly for VSA1. - 5th Nov 1998 avg - Fixed blit buffer organization using CPU_WRITE instruction. Support for older chipsets (color treatment and different CPU_WRITE opcode). @@ -115,35 +108,50 @@ #include "extensions/xf86dgastr.h" #endif +#ifdef XF86VGA16 +#define MONOVGA +#endif +#if !defined(MONOVGA) && !defined(XF86VGA16) #include "vga256.h" +#endif + #include "cyrix.h" pciTagRec CyrixPciTag; extern vgaHWCursorRec vgaHWCursor; -#define NUM_STD_CRTC_REGS 25 -#define NUM_EXT_CRTC_REGS 16 - typedef struct { vgaHWRec std; /* IBM VGA */ struct vgaCYRIXext - { - /* override of miscellaneous output register value */ - - unsigned char miscOutput; - - /* override of standard CRTC register values */ - - unsigned char stdCRTCregs[NUM_STD_CRTC_REGS]; - - /* extended CRTC register values (specific to MediaGX) */ - - unsigned char extCRTCregs[NUM_EXT_CRTC_REGS]; + { /* extended SoftVGA registers */ + unsigned char VerticalTimingExtension; + unsigned char ExtendedAddressControl; + unsigned char ExtendedOffset; + unsigned char ExtendedColorControl; + unsigned char DisplayCompression; + unsigned char DriverControl; + unsigned char DACControl; + unsigned char ClockControl; + unsigned char CrtClockFrequency; + unsigned char CrtClockFrequencyFraction; + unsigned char RefreshRate; + + /* display controller hardware registers */ + CARD32 DcGeneralCfg; + CARD32 DcCursStOffset; + CARD32 DcCbStOffset; + CARD32 DcLineDelta; + CARD32 DcBufSize; + CARD32 DcCursorX; + CARD32 DcCursorY; + CARD32 DcCursorColor; /* graphics pipeline registers */ - CARD32 GpBlitStatus; + + /* save area for cursor image */ + char cursorPattern[256]; } ext; } vgaCYRIXRec, *vgaCYRIXPtr; @@ -158,9 +166,11 @@ static void CYRIXRestore(); static void CYRIXAdjust(); +#ifndef MONOVGA static void CYRIXFbInit(); static Bool CYRIXScreenInit(); static Bool CYRIXPitchAdjust(); +#endif void CYRIXSetRead(); void CYRIXSetWrite(); @@ -177,7 +187,11 @@ CYRIXAdjust, vgaHWSaveScreen, (void (*)())NoopDDA, /* CYRIXGetMode */ +#ifndef MONOVGA CYRIXFbInit, +#else + (void (*)())NoopDDA, /* CYRIXFbInit */ +#endif CYRIXSetRead, CYRIXSetWrite, CYRIXSetReadWrite, @@ -191,9 +205,9 @@ VGA_NO_DIVIDE_VERT, /* ChipInterlaceType */ {0,}, /* ChipOptionFlags */ 8, /* ChipRounding */ - TRUE, /* ChipUseLinearAddressing */ - 0x40800000, /* ChipLinearBase */ - 0x001FFFFF, /* ChipLinearSize */ + FALSE, /* ChipUseLinearAddressing */ + 0, /* ChipLinearBase */ + 0, /* ChipLinearSize */ TRUE, /* ChipHas16bpp */ FALSE, /* ChipHas24bpp */ FALSE, /* ChipHas32bpp */ @@ -207,10 +221,6 @@ char* GXregisters; -int CYRIXvsaversion; /* VSA version */ -#define CYRIX_VSA1 1 -#define CYRIX_VSA2 2 - int CYRIXcbufferAddress; /* relative to video base */ int CYRIXoffscreenAddress; int CYRIXcursorAddress; @@ -225,94 +235,6 @@ #define newstate ((vgaCYRIXPtr)vgaNewVideoState) -typedef struct { - int xsize; - int ysize; - int clock; - unsigned char miscOutput; - unsigned char stdCRTCregs[NUM_STD_CRTC_REGS]; - unsigned char extCRTCregs[NUM_EXT_CRTC_REGS]; -} vgaCYRIXmode; - -vgaCYRIXmode CYRIXmodes[] = -{ -/*------------------------------------------------------------------------------*/ - { 640, 480, /* 640x480 */ - 25, /* 25 MHz clock = 60 Hz refresh rate */ - 0xE3, /* miscOutput register */ - { 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E, /* standard CRTC */ - 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xEA, 0x0C, 0xDF, 0x50, 0x00, 0xE7, 0x04, 0xE3, 0xFF }, - { 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */ - 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00 } }, -/*------------------------------------------------------------------------------*/ - { 800, 600, /* 800x600 */ - 40, /* 40 MHz clock = 60 Hz refresh rate */ - 0x23, /* miscOutput register */ - { 0x7F, 0x63, 0x64, 0x82, 0x6B, 0x1B, 0x72, 0xF0, /* standard CRTC */ - 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x59, 0x0D, 0x57, 0x64, 0x00, 0x57, 0x73, 0xE3, 0xFF }, - { 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */ - 0x00, 0x00, 0x01, 0x03, 0xA0, 0x50, 0x00, 0x00 } }, -/*------------------------------------------------------------------------------*/ - { 1024, 768, /* 1024x768 */ - 65, /* 65 MHz clock = 60 Hz refresh rate */ - 0xE3, /* miscOutput register */ - { 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xF5, /* standard CRTC */ - 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x0A, 0xFF, 0x80, 0x00, 0xFF, 0x25, 0xE3, 0xFF }, - { 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */ - 0x00, 0x00, 0x01, 0x03, 0x80, 0x41, 0x00, 0x00 } }, -/*------------------------------------------------------------------------------*/ - { 1280, 1024, /* 1280x1024 */ - 108, /* 108 MHz clock = 60 Hz refresh rate */ - 0x23, /* miscOutput register */ - { 0xCF, 0x9F, 0xA0, 0x92, 0xAA, 0x19, 0x28, 0x52, /* standard CRTC */ - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x04, 0xFF, 0xA0, 0x00, 0x00, 0x29, 0xE3, 0xFF }, - { 0x00, 0x51, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */ - 0x00, 0x00, 0x01, 0x03, 0x80, 0x6C, 0x00, 0x00 } }, -/*------------------------------------------------------------------------------*/ - { 640, 480, /* 640x480 */ - 31, /* 31.5 MHz clock = 75 Hz refresh rate */ - 0xE3, /* miscOutput register */ - { 0x64, 0x4F, 0x4F, 0x88, 0x54, 0x9B, 0xF2, 0x1F, /* standard CRTC */ - 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xE1, 0x04, 0xDF, 0x50, 0x00, 0xDF, 0xF3, 0xE3, 0xFF }, - { 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */ - 0x00, 0x00, 0x01, 0x03, 0xA0, 0x3F, 0x00, 0x00 } }, -/*------------------------------------------------------------------------------*/ - { 800, 600, /* 800x600 */ - 99, /* 99 MHz clock = 75 Hz refresh rate */ - 0x23, /* miscOutput register */ - { 0x7F, 0x63, 0x63, 0x83, 0x68, 0x11, 0x6F, 0xF0, /* standard CRTC */ - 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x59, 0x1C, 0x57, 0x64, 0x00, 0x57, 0x70, 0xE3, 0xFF }, - { 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */ - 0x00, 0x00, 0x01, 0x03, 0xA0, 0x63, 0x00, 0x00 } }, -/*------------------------------------------------------------------------------*/ - { 1024, 768, /* 1024x768 */ - 79, /* 79 MHz clock = 75 Hz refresh rate */ - 0xE3, /* miscOutput register */ - { 0x9F, 0x7F, 0x7F, 0x83, 0x84, 0x8F, 0x1E, 0xF5, /* standard CRTC */ - 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x04, 0xFF, 0x80, 0x00, 0xFF, 0x1F, 0xE3, 0xFF }, - { 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */ - 0x00, 0x00, 0x01, 0x03, 0x80, 0x4F, 0x00, 0x00 } }, -/*------------------------------------------------------------------------------*/ - { 1280, 1024, /* 1280x1024 */ - 135, /* 135 MHz clock = 75 Hz refresh rate */ - 0x23, /* miscOutput register */ - { 0xCE, 0x9F, 0x9F, 0x92, 0xA4, 0x15, 0x28, 0x52, /* standard CRTC */ - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x04, 0xFF, 0xA0, 0x00, 0x00, 0x29, 0xE3, 0xFF }, - { 0x00, 0x51, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */ - 0x00, 0x00, 0x01, 0x03, 0x80, 0x87, 0x00, 0x00 } }, -/*------------------------------------------------------------------------------*/ -}; - -#define NUM_CYRIX_MODES sizeof(CYRIXmodes)/sizeof(vgaCYRIXmode) - static char * CYRIXIdent(n) int n; @@ -478,6 +400,7 @@ vga256InfoRec.bankedMono = TRUE; OFLG_SET(CLOCK_OPTION_PROGRAMABLE, &vga256InfoRec.clockOptions); +#ifndef MONOVGA /* define option set valid for the driver */ OFLG_SET(OPTION_SW_CURSOR, &CYRIX.ChipOptionFlags); OFLG_SET(OPTION_HW_CURSOR, &CYRIX.ChipOptionFlags); @@ -496,12 +419,13 @@ CYRIX.ChipLinearSize = (1024 * vga256InfoRec.videoRam); CYRIX.ChipUseLinearAddressing = TRUE; +#endif /* map the entire area from GX_BASE (scratchpad area) up to the end of the control registers */ GXregisters = (char*)xf86MapVidMem(vga256InfoRec.scrnIndex, EXTENDED_REGION, - (void*)physbase, 0x20000); + (void*)physbase, 0x9000); if (!GXregisters) { ErrorF("%s %s: Cannot map hardware registers\n", @@ -509,80 +433,27 @@ goto probeFailed; } - /* check VSA version */ - /* VSA2 contains a "CX" signature at registers 0x35 and 0x36. */ - /* The SoftVGA interface changed slightly for VSA2. Originally, */ - /* VSA2 was intended for MXi only, but it may someday be */ - /* provided for MediaGX systems as well. */ - - CYRIXvsaversion = CYRIX_VSA2; - outb(vgaIOBase + 4, 0x35); - if (inb(vgaIOBase + 5) != 'C') CYRIXvsaversion = CYRIX_VSA1; - outb(vgaIOBase + 4, 0x36); - if (inb(vgaIOBase + 5) != 'X') CYRIXvsaversion = CYRIX_VSA1; - if (CYRIXvsaversion == CYRIX_VSA1) - { - ErrorF("%s %s: VSA1 detected\n", - XCONFIG_PROBED, vga256InfoRec.name); - } - else - { - ErrorF("%s %s: VSA2 detected\n", - XCONFIG_PROBED, vga256InfoRec.name); - } return(TRUE); } -/*------------------------------------------------------------------------*\ -** FbInit() -** -** From README file: "The FbInit() function is required for drivers with -** accelerated graphics support. It is used to replace default cfb.banked -** functions with accelerated chip-specific versions. -** -** For the Cyrix driver, this routine is also used to allocate video -** memory. This is more complicated than it needs to be... -** -** For VSA1, SoftVGA manages all of graphics memory, including the -** compression buffer, cursor buffer, and offscreen memory. The driver -** should not allocate memory itself. For offscreen memory it reads -** registers 0x3C and 0x3D. For the cursor buffer it reads the hardware -** register after validating a mode. For compression, it just sets bit 0 -** of register 0x49 if it wants to use compression, and SoftVGA will -** enable it if memory has been allocated. -** -** This model, however, breaks down for this driver. There is a bug in -** SoftVGA that keeps the 0x3C register from working properly. This bug -** also prevents compression from being enabled when using a virtual -** desktop. This driver also cannot use the memory past 2 Meg, which -** effects the memory calculation. -** -** Therefore, this driver does what it is not supposed to and allocates -** video memory itself. But, this is required due to bugs in SoftVGA and, -** as it turns out, works out fine (with limiting compression use). -** -** For VSA2, the driver is supposed to do this allocation itself. -\*------------------------------------------------------------------------*/ +#ifndef MONOVGA static void CYRIXFbInit() { int lineDelta = vga256InfoRec.displayWidth * (vgaBitsPerPixel / 8); int virtualDelta = vga256InfoRec.virtualX * (vgaBitsPerPixel / 8); - int base; vgaSetScreenInitHook(CYRIXScreenInit); - /* always put the cursor at the end of video memory. */ - - CYRIXcursorAddress = CYRIX.ChipLinearSize - 256; - /* offscreen memory is, normally, right after the frame buffer; + always put the cursor at the end of video memory. + (It would be nice to use the ignored 64KB block at the end of the video memory (2112 - 2048) for the hardware cursor, but it is not mapped. This will not be a problem in Xfree 3.9 */ - CYRIXoffscreenAddress = (lineDelta * vga256InfoRec.virtualY); - CYRIXoffscreenSize = CYRIXcursorAddress - CYRIXoffscreenAddress; + CYRIXcursorAddress = CYRIX.ChipLinearSize - 256; + CYRIXoffscreenSize = CYRIXcursorAddress - CYRIXoffscreenAddress; /* if there is enough room between lines, put the compression buffer there */ @@ -591,7 +462,7 @@ CYRIXcbLineDelta = (lineDelta >> 2); if (xf86Verbose > 1) ErrorF("%s %s: Interleaving frame buffer and compression buffer\n", - XCONFIG_PROBED, vga256InfoRec.name); + XCONFIG_PROBED, vga256InfoRec.name); } /* otherwise, put it directly after the virtual frame */ else @@ -600,7 +471,7 @@ if (cbuffer_size > CYRIXoffscreenSize) { CYRIXcbLineDelta = 0; ErrorF("%s %s: No room for the compression buffer\n", - XCONFIG_PROBED, vga256InfoRec.name); + XCONFIG_PROBED, vga256InfoRec.name); } else { CYRIXcbufferAddress = CYRIXoffscreenAddress; @@ -609,43 +480,25 @@ CYRIXoffscreenSize -= cbuffer_size; } } - /* print results of offscreen memory configuration */ - - if (CYRIXoffscreenSize <= 0) - { - ErrorF("%s %s: No offscreen memory available.\n", - XCONFIG_PROBED, vga256InfoRec.name); - } - else - { - ErrorF("%s %s: Offscreen memory from 0x%8.8X-0x%8.8X\n", - XCONFIG_PROBED, vga256InfoRec.name, - CYRIXoffscreenAddress, - CYRIXoffscreenAddress+CYRIXoffscreenSize-1); - } - - /* call CYRIXAccelInit to setup the XAA accelerated functions */ - + /* call CYRIXAccelInit to setup the XAA accelerated functions */ if (!OFLG_ISSET(OPTION_NOACCEL, &vga256InfoRec.options)) CYRIXAccelInit(); /* install hardware cursor routines */ - if (OFLG_ISSET(OPTION_HW_CURSOR, &vga256InfoRec.options)) - { if (CYRIXoffscreenSize > 0) + { if (CYRIXoffscreenSize >= 0) { vgaHWCursor.Initialized = TRUE; vgaHWCursor.Init = CYRIXCursorInit; vgaHWCursor.Restore = CYRIXRestoreCursor; vgaHWCursor.Warp = CYRIXWarpCursor; vgaHWCursor.QueryBestSize = CYRIXQueryBestSize; - ErrorF("%s %s: Using hardware cursor at %8.8X\n", - XCONFIG_PROBED, vga256InfoRec.name, CYRIXcursorAddress); + if (xf86Verbose) + ErrorF("%s %s: Using hardware cursor\n", + XCONFIG_PROBED, vga256InfoRec.name); } else - { ErrorF("%s %s: No room for hardware cursor\n", - XCONFIG_PROBED, vga256InfoRec.name); - } + XCONFIG_PROBED, vga256InfoRec.name); } } @@ -696,6 +549,7 @@ return pitch; } +#endif /* not MONOVGA */ static void @@ -747,121 +601,210 @@ static void CYRIXresetVGA() -{ - int i; +{ unsigned char temp; + /* switch off compression and cursor the hard way */ + GX_REG(DC_UNLOCK) = DC_UNLOCK_VALUE; + GX_REG(DC_GENERAL_CFG) &= ~(DC_GCFG_CMPE | DC_GCFG_DECE | DC_GCFG_FDTY | DC_GCFG_CURE); + GX_REG(DC_UNLOCK) = 0; + CYRIXmarkLinesDirty(); /* reset SoftVGA extensions to standard VGA behaviour */ - - for (i = 0; i < NUM_EXT_CRTC_REGS; i++) - { - outb(vgaIOBase + 4, 0x40 + i); - outb(vgaIOBase + 5, 0x00); - } + outb(vgaIOBase + 4, CrtcExtendedAddressControl); + temp = inb(vgaIOBase + 5); + outb(vgaIOBase + 5, temp & 0xf8); + outb(vgaIOBase + 4, CrtcExtendedStartAddress); + outb(vgaIOBase + 5, 0x00); + outb(vgaIOBase + 4, CrtcWriteMemoryAperture); + temp = inb(vgaIOBase + 5); + outb(vgaIOBase + 5, temp & 0xe0); + outb(vgaIOBase + 4, CrtcReadMemoryAperture); + temp = inb(vgaIOBase + 5); + outb(vgaIOBase + 5, temp & 0xe0); + outb(vgaIOBase + 4, CrtcDriverControl); + temp = inb(vgaIOBase + 5); + outb(vgaIOBase + 5, temp & 0xfe); + outb(vgaIOBase + 4, CrtcDisplayCompression); + temp = inb(vgaIOBase + 5); + outb(vgaIOBase + 5, temp & 0xf0); } static void CYRIXRestore(restore) vgaCYRIXPtr restore; -{ unsigned char i, temp, temp2; - unsigned long value; - - /* unlock extended CRTC registers */ - - outb(vgaIOBase + 4, 0x30); - outb(vgaIOBase + 5, 0x57); - outb(vgaIOBase + 5, 0x4C); +{ unsigned char temp; + vgaProtect(TRUE); /* Blank the screen */ - /* SIGNAL THE BEGINNING OF THE MODE SWITCH - SoftVGA will hold off validating the back end hardware. */ - - outb(vgaIOBase + 4, CrtcModeSwitchControl); - outb(vgaIOBase + 5, 0x01); + /* it would be ideal to be able to use the ModeSwitchControl + register to protect SoftVGA from reading the configuration + before all registers have been written. But that bit must be + set somewhere in the middle of vgaHWRestore (after restoring + the font). Luckily things seem to work without it. */ /* restore standard VGA portion */ - CYRIXresetVGA(); vgaHWRestore((vgaHWPtr)restore); + CYRIXmarkLinesDirty(); - /* override restored miscellaneous output regiter value */ - - outb(0x3C2, restore->ext.miscOutput); - - /* override restored standard CRTC register values */ - - outb(vgaIOBase + 4, 0x11); - outb(vgaIOBase + 5, 0x00); - for (i = 0; i < NUM_STD_CRTC_REGS; i++) - { - outb(vgaIOBase + 4, i); - outb(vgaIOBase + 5, restore->ext.stdCRTCregs[i]); - } - /* restore SoftVGA extended registers */ + outb(vgaIOBase + 4, CrtcDriverControl); + temp = inb(vgaIOBase + 5); + outb(vgaIOBase + 5, (restore->ext.DriverControl & 0x01) + | (temp & 0xfe)); + + outb(vgaIOBase + 4, CrtcVerticalTimingExtension); + temp = inb(vgaIOBase + 5); + outb(vgaIOBase + 5, (restore->ext.VerticalTimingExtension & 0x55) + | (temp & 0xaa)); + + outb(vgaIOBase + 4, CrtcExtendedAddressControl); + temp = inb(vgaIOBase + 5); + outb(vgaIOBase + 5, (restore->ext.ExtendedAddressControl & 0x07) + | (temp & 0xf8)); + + outb(vgaIOBase + 4, CrtcExtendedOffset); + temp = inb(vgaIOBase + 5); + outb(vgaIOBase + 5, (restore->ext.ExtendedOffset & 0x03) + | (temp & 0xfc)); + + outb(vgaIOBase + 4, CrtcExtendedColorControl); + temp = inb(vgaIOBase + 5); + outb(vgaIOBase + 5, (restore->ext.ExtendedColorControl & 0x07) + | (temp & 0xf8)); + + outb(vgaIOBase + 4, CrtcDisplayCompression); + temp = inb(vgaIOBase + 5); + outb(vgaIOBase + 5, (restore->ext.DisplayCompression & 0x0f) + | (temp & 0xf0)); + + outb(vgaIOBase + 4, CrtcDACControl); + temp = inb(vgaIOBase + 5); + outb(vgaIOBase + 5, (restore->ext.DACControl & 0x0e) + | (temp & 0xf1)); + + if (restore->std.NoClock >= 0) + { outb(vgaIOBase + 4, CrtcClockControl); + temp = inb(vgaIOBase + 5); + outb(vgaIOBase + 5, (restore->ext.ClockControl & 0xb0) + | (temp & 0x4f)); + + outb(vgaIOBase + 4, CrtcClockFrequency); + outb(vgaIOBase + 5, restore->ext.CrtClockFrequency); + + outb(vgaIOBase + 4, CrtcClockFrequencyFraction); + outb(vgaIOBase + 5, restore->ext.CrtClockFrequencyFraction); + + outb(vgaIOBase + 4, CrtcRefreshRate); + outb(vgaIOBase + 5, restore->ext.RefreshRate); + } + + /* let SoftVGA programming settle before we access DC registers, + but don't wait too long */ + usleep(1000); + CYRIXmarkLinesDirty(); + + /* restore display controller hardware registers */ +#ifndef MONOVGA +#define DCFG_MASK (DC_GCFG_FDTY | DC_GCFG_DECE | DC_GCFG_CMPE) +#define GPBS_MASK (BC_16BPP | BC_FB_WIDTH_2048) - for (i = 0; i < NUM_EXT_CRTC_REGS; i++) - { - outb(vgaIOBase + 4, 0x40+i); - outb(vgaIOBase + 5, restore->ext.extCRTCregs[i]); - } + GX_REG(DC_UNLOCK) = DC_UNLOCK_VALUE; - /* signal the end of the mode switch */ + GX_REG(DC_CURS_ST_OFFSET) = restore->ext.DcCursStOffset; + GX_REG(DC_CB_ST_OFFSET) = restore->ext.DcCbStOffset; + GX_REG(DC_LINE_DELTA) = (GX_REG(DC_LINE_DELTA) & 0xFFC00FFF) + | (restore->ext.DcLineDelta & 0x003FF000); + GX_REG(DC_BUF_SIZE) = (GX_REG(DC_BUF_SIZE) & 0xFFFF01FF) + | (restore->ext.DcBufSize & 0x0000FE00); + GX_REG(DC_CURSOR_X) = restore->ext.DcCursorX; + GX_REG(DC_CURSOR_Y) = restore->ext.DcCursorY; + GX_REG(DC_CURSOR_COLOR) = restore->ext.DcCursorColor; - outb(vgaIOBase + 4, CrtcModeSwitchControl); - outb(vgaIOBase + 5, 0x00); + GX_REG(DC_GENERAL_CFG) = (GX_REG(DC_GENERAL_CFG) & (~DCFG_MASK)) + | (restore->ext.DcGeneralCfg & DCFG_MASK); - /* wait until SoftVGA has validated the mode. - This is for VSA1 only, where SoftVGA waits until the next - vertical blank to recalculate the hardware state. For VSA2 - the hardware us updated immediately, so this is not needed. - THIS MUST BE DONE FOR VSA1 before loading the GP_BLT_STATUS - register, otherwise SoftVGA will override the value. */ + GX_REG(DC_UNLOCK) = 0; - if (CYRIXvsaversion == CYRIX_VSA1) - { - outb(vgaIOBase + 4, 0x33); - while(inb(vgaIOBase + 5) & 0x80); - } + GX_REG(GP_BLIT_STATUS) = (GX_REG(GP_BLIT_STATUS) & (~GPBS_MASK)) + | (restore->ext.GpBlitStatus & GPBS_MASK); - /* overrite what SoftVGA may have stored into GP_BLIT_STATUS */ + /* restore cursor pattern */ + if (restore->ext.DcCursStOffset < 1024 * vga256InfoRec.videoRam) + memcpy((char*)vgaLinearBase + restore->ext.DcCursStOffset, + restore->ext.cursorPattern, 256); +#endif - GX_REG(GP_BLIT_STATUS) = restore->ext.GpBlitStatus; + vgaProtect(FALSE); /* Turn on screen */ } static void * CYRIXSave(save) vgaCYRIXPtr save; -{ unsigned char i; - struct vgaCYRIXext ext; +{ struct vgaCYRIXext ext; - /* save miscellaneous output register */ +#ifndef MONOVGA + /* save graphics pipeline registers */ + ext.GpBlitStatus = GX_REG(GP_BLIT_STATUS); - ext.miscOutput = inb(0x3CC); + /* save display controller hardware registers */ + GX_REG(DC_UNLOCK) = DC_UNLOCK_VALUE; + ext.DcGeneralCfg = GX_REG(DC_GENERAL_CFG); + ext.DcCursStOffset = GX_REG(DC_CURS_ST_OFFSET); + ext.DcCbStOffset = GX_REG(DC_CB_ST_OFFSET); + ext.DcLineDelta = GX_REG(DC_LINE_DELTA); + ext.DcBufSize = GX_REG(DC_BUF_SIZE); + ext.DcCursorX = GX_REG(DC_CURSOR_X); + ext.DcCursorY = GX_REG(DC_CURSOR_Y); + ext.DcCursorColor = GX_REG(DC_CURSOR_COLOR); + GX_REG(DC_UNLOCK) = 0; + + /* save cursor pattern. + In the 3.3.1 solution, we don't need to do this + if it is in the extra 64KB block of frame buffer memory + that we ignore (and is not mapped anyway) */ + if (ext.DcCursStOffset < 1024 * vga256InfoRec.videoRam) + memcpy(ext.cursorPattern, + (char*)vgaLinearBase + ext.DcCursStOffset, 256); +#endif - /* save standard CRTC registers */ + /* save SoftVGA extended registers */ + outb(vgaIOBase + 4, CrtcVerticalTimingExtension); + ext.VerticalTimingExtension = inb(vgaIOBase + 5); - for (i = 0; i < NUM_STD_CRTC_REGS; i++) - { - outb(vgaIOBase + 4, i); - ext.stdCRTCregs[i] = inb(vgaIOBase + 5); - } + outb(vgaIOBase + 4, CrtcExtendedAddressControl); + ext.ExtendedAddressControl = inb(vgaIOBase + 5); - /* save extended CRTC registers */ + outb(vgaIOBase + 4, CrtcExtendedOffset); + ext.ExtendedOffset = inb(vgaIOBase + 5); - for (i = 0; i < NUM_EXT_CRTC_REGS; i++) - { - outb(vgaIOBase + 4, 0x40+i); - ext.extCRTCregs[i] = inb(vgaIOBase + 5); - } + outb(vgaIOBase + 4, CrtcExtendedColorControl); + ext.ExtendedColorControl = inb(vgaIOBase + 5); - /* save graphics pipeline registers */ + outb(vgaIOBase + 4, CrtcDisplayCompression); + ext.DisplayCompression = inb(vgaIOBase + 5); - ext.GpBlitStatus = GX_REG(GP_BLIT_STATUS); + outb(vgaIOBase + 4, CrtcDriverControl); + ext.DriverControl = inb(vgaIOBase + 5); - /* save standard VGA portion */ + outb(vgaIOBase + 4, CrtcDACControl); + ext.DACControl = inb(vgaIOBase + 5); + + outb(vgaIOBase + 4, CrtcClockControl); + ext.ClockControl = inb(vgaIOBase + 5); + + outb(vgaIOBase + 4, CrtcClockFrequency); + ext.CrtClockFrequency = inb(vgaIOBase + 5); + outb(vgaIOBase + 4, CrtcClockFrequencyFraction); + ext.CrtClockFrequencyFraction = inb(vgaIOBase + 5); + + outb(vgaIOBase + 4, CrtcRefreshRate); + ext.RefreshRate = inb(vgaIOBase + 5); + + /* save standard VGA portion */ CYRIXresetVGA(); save = (vgaCYRIXPtr)vgaHWSave((vgaHWPtr)save, sizeof(vgaCYRIXRec)); save->ext = ext; + return ((void *) save); } @@ -869,108 +812,101 @@ static Bool CYRIXInit(mode) DisplayModePtr mode; -{ int i, mode_index; - int clock = vga256InfoRec.clock[mode->Clock] / 1000; - int min, diff; - int offset_shift = (vgaBitsPerPixel == 16) ? 2 : +{ int offset_shift = (vgaBitsPerPixel == 16) ? 2 : (vgaBitsPerPixel == 8) ? 3 : 4; int line_offset = vga256InfoRec.displayWidth >> offset_shift; /* initialize standard VGA portion */ - if (!vgaHWInit(mode,sizeof(vgaCYRIXRec))) return(FALSE); - /* search for specified mode in the table */ - /* Need to find the entry with the closest dot clock value */ - /* Assume within at least 200 MHz and then maintain closest natch. */ - - mode_index = 0; - min = 200; - for (i = 0; i < NUM_CYRIX_MODES; i++) - { - diff = clock - CYRIXmodes[i].clock; - if (diff < 0) diff = -diff; - if ((mode->CrtcHDisplay == CYRIXmodes[i].xsize) && - (mode->CrtcVDisplay == CYRIXmodes[i].ysize) && - (diff < min)) - { - mode_index = i; - min = diff; - } - } - - /* override standard miscOutput register value */ - - newstate->ext.miscOutput = CYRIXmodes[mode_index].miscOutput; + newstate->std.CRTC[19] = line_offset; - /* override standard CRTC register values */ + /* initialize SoftVGA extended registers */ + newstate->ext.VerticalTimingExtension = + ((mode->CrtcVSyncStart & 0x400) >> 4) | + (((mode->CrtcVDisplay - 1) & 0x400) >> 8) | + (((mode->CrtcVTotal - 2) & 0x400) >> 10) | + ((mode->CrtcVSyncStart & 0x400) >> 6); - for (i = 0; i < NUM_STD_CRTC_REGS; i++) - { - newstate->ext.stdCRTCregs[i] = - CYRIXmodes[mode_index].stdCRTCregs[i]; - } - - /* set extended CRTC registers */ - - for (i = 0; i < NUM_EXT_CRTC_REGS; i++) - { - newstate->ext.extCRTCregs[i] = - CYRIXmodes[mode_index].extCRTCregs[i]; - } - - /* override pitch from the mode tables */ - /* (same tables are used for 8BPP and 16BPP) */ + if (vgaBitsPerPixel < 8) + newstate->ext.ExtendedAddressControl = EAC_DIRECT_FRAME_BUFFER; + else + newstate->ext.ExtendedAddressControl = EAC_DIRECT_FRAME_BUFFER | + EAC_PACKED_CHAIN4; - newstate->ext.stdCRTCregs[19] = line_offset; - newstate->ext.extCRTCregs[5] = ((line_offset >> 8) & 0x03); + newstate->ext.ExtendedOffset = ((line_offset >> 8) & 0x03); - /* override color control from the mode tables */ - /* (same tables are used for 8BPP and 16BPP) */ + newstate->ext.ExtendedColorControl = (vgaBitsPerPixel == 16) + ? ECC_16BPP | ECC_565_FORMAT + : ECC_8BPP; + + /* display compression is set using the DC registers */ + newstate->ext.DisplayCompression = 0x00; + + /* we drive the palette through the display controller (in new + chipsets only) in 8bpp and 16bpp (that is, whenever the + hardware cursor is used). */ + if (vgaBitsPerPixel < 8) + newstate->ext.DriverControl = 0x00; + else + newstate->ext.DriverControl = DRVCT_DISPLAY_DRIVER_ACTIVE; - newstate->ext.extCRTCregs[6] = (vgaBitsPerPixel == 16) - ? ECC_16BPP | ECC_565_FORMAT : ECC_8BPP; + /* set `16 bit bus' or else compression will hang the + system in 16bpp mode */ + if (vgaBitsPerPixel == 16) + newstate->ext.DACControl = DACCT_ENABLE_16BIT_BUS; + else + newstate->ext.DACControl = 0; - /* enable display compression when appropriate */ - if (CYRIXvsaversion == CYRIX_VSA1) - { - /* For VSA1, SoftVGA manages the compression buffer. */ - /* Enabling compression directly causes unpredictable results. */ - /* Only enable if not panning (there is a bug in SoftVGA that */ - /* will put the compression buffer in the wrong place when */ - /* using a virtual desktop. */ - /* By setting bit 0 of register 0x49, SoftVGA will enable */ - /* compression whenever possible, based on memory available */ - /* and starting address of memory. */ - - if ((mode->CrtcVDisplay == vga256InfoRec.virtualY) && - (mode->CrtcHDisplay == vga256InfoRec.virtualX)) - { - newstate->ext.extCRTCregs[9] = 0x01; - ErrorF("%s %s: Display compression enabled.\n", - XCONFIG_PROBED, vga256InfoRec.name); - } - else - { - ErrorF("%s %s: Display compression disabled.\n", - XCONFIG_PROBED, vga256InfoRec.name); - } + if (newstate->std.NoClock >= 0) + { int entier_clock = (vga256InfoRec.clock[mode->Clock] / 1000); + int clock_fraction = (vga256InfoRec.clock[mode->Clock] / 100) + - (entier_clock * 10); + + newstate->ext.ClockControl = CLKCT_EXT_CLOCK_MODE; + newstate->ext.CrtClockFrequency = entier_clock; + newstate->ext.CrtClockFrequencyFraction = clock_fraction; + newstate->ext.RefreshRate = 0 /* relevant to VGA BIOS only */; + } + +#ifndef MONOVGA + /* initialize masked contents of display controller + hardware registers. */ + newstate->ext.DcCursStOffset = CYRIXcursorAddress; + newstate->ext.DcCbStOffset = CYRIXcbufferAddress; + newstate->ext.DcLineDelta = CYRIXcbLineDelta << 12; + newstate->ext.DcBufSize = 0x41 << 9; + newstate->ext.DcCursorX = 0; + newstate->ext.DcCursorY = 0; + newstate->ext.DcCursorColor = 0; + + /* Compression is enabled only when a buffer was allocated by + FbInit and provided that the displayed screen is the virtual + screen. If the line delta is not 1024 or 2048, entire frames + will be flagged dirty as opposed to lines. Problems with 16bpp + and line-dirty flagging seem to have been solved now. */ + if (CYRIXcbLineDelta != 0 && + mode->CrtcVDisplay == vga256InfoRec.virtualY && + mode->CrtcHDisplay == vga256InfoRec.virtualX) + { newstate->ext.DcGeneralCfg = DC_GCFG_DECE + | DC_GCFG_CMPE; + if (/* vgaBitsPerPixel != 8 || -- this is OK now */ + (vga256InfoRec.displayWidth * (vgaBitsPerPixel / 8)) & 0x03FF) + newstate->ext.DcGeneralCfg |= DC_GCFG_FDTY; } else - { - /* ### TO DO ### */ - /* Enable display compression directly for VSA2. */ - /* For VSA2, the display driver manages all graphics memory. */ - } + newstate->ext.DcGeneralCfg = 0; - /* initialize the graphics pipeline registers */ + /* initialize the graphics pipeline registers */ newstate->ext.GpBlitStatus = ((vga256InfoRec.displayWidth == 2048) ? BC_FB_WIDTH_2048 : BC_FB_WIDTH_1024) | ((vgaBitsPerPixel == 16) ? BC_16BPP : BC_8BPP); +#endif + return(TRUE); } @@ -978,68 +914,31 @@ CYRIXAdjust(x, y) int x, y; { int Base = (y * vga256InfoRec.displayWidth + x); - unsigned long active, sync, count1, count2; if (vgaBitsPerPixel > 8) Base *= (vgaBitsPerPixel / 8); if (vgaBitsPerPixel < 8) Base /= 2; - /* wait until out of active display area */ - - active = GX_REG(DC_V_TIMING_1) & 0x07FF; - sync = GX_REG(DC_V_TIMING_3) & 0x07FF; - - do - { - /* read twice to avoid transition values */ - - count1 = GX_REG(DC_V_LINE_CNT) & 0x07FF; - count2 = GX_REG(DC_V_LINE_CNT) & 0x07FF; - } while ((count1 != count2) || (count1 < active) || (count1 >= sync)); - - /* load the start address directly */ - + /* doing this using the SoftVGA registers does not work reliably */ GX_REG(DC_UNLOCK) = DC_UNLOCK_VALUE; GX_REG(DC_FB_ST_OFFSET) = Base; GX_REG(DC_UNLOCK) = 0; } -/*------------------------------------------------------------------------*\ -** ValidMode() -** -** From README file: "The ValidMode() function is required. It is used to -** check for any chipset dependent reasons why a graphics mode might not be -** valid. It gets called by higher levels of the code after the Probe() -** stage. In many cases no special checking will be required and this -** function will simply return TRUE always." -** -** For the Cyrix driver, this routine loops through modes provided in a -** table at the beginning of this file and returns OK if it finds a match. -** These tables were required to make the standard VESA 60 Hz and 75 Hz -** modes work correctly. Doing this, however, takes away the flexibility -** of adding different resolutions or different refresh rates to the -** XF86Config file. -\*------------------------------------------------------------------------*/ - static int CYRIXValidMode(mode, verbose, flag) DisplayModePtr mode; Bool verbose; int flag; -{ - int i; - - /* loop through table of modes */ - - for (i = 0; i < NUM_CYRIX_MODES; i++) - { - if ((mode->CrtcHDisplay == CYRIXmodes[i].xsize) && - (mode->CrtcVDisplay == CYRIXmodes[i].ysize)) - { - return MODE_OK; - } +{ /* note (avg): there seems to be a lot more to this if you look + at the GGI code (adjustment). */ + if (mode->CrtcHSyncStart - mode->CrtcHDisplay >= 24 || + mode->CrtcHSyncStart - mode->CrtcHDisplay <= 8) + { if (verbose) + ErrorF("%s %s: mode %s: horizontal sync out of range (sync - display should be between 8 and 24)\n", + XCONFIG_PROBED, vga256InfoRec.name, mode->name + ); + return MODE_HSYNC; } - return MODE_BAD; + return(MODE_OK); } - -/* END OF FILE */ diff -ruN XFree86-3.3.5/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/gxrender.c XFree86-3.3.3.1/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/gxrender.c --- XFree86-3.3.5/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/gxrender.c Thu Jun 24 01:59:41 1999 +++ XFree86-3.3.3.1/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/gxrender.c Wed Dec 31 19:00:00 1969 @@ -1,1237 +0,0 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/gxrender.c,v 1.1.2.1 1999/06/24 05:59:41 hohndel Exp $ */ -/* -//--------------------------------------------------------------------------- -// gxrender.c -// -// This file gives examples of using the MediaGX graphics unit to provide -// acceleration for 2D display drivers. It is intended to provide an -// absraction layer for new display driver development. This code handles -// the quirks of the MediaGX graphics unit to allow faster developemt times -// for new drivers. -//--------------------------------------------------------------------------- -*/ - -/* GRAPHICS PIPELINE REGISTER DEFINITIONS */ - -#define GP_DST_XCOOR 0x8100 /* x destination origin */ -#define GP_DST_YCOOR 0x8102 /* y destination origin */ -#define GP_WIDTH 0x8104 /* pixel width */ -#define GP_HEIGHT 0x8106 /* pixel height */ -#define GP_SRC_XCOOR 0x8108 /* x source origin */ -#define GP_SRC_YCOOR 0x810A /* y source origin */ - -#define GP_VECTOR_LENGTH 0x8104 /* vector length */ -#define GP_INIT_ERROR 0x8106 /* vector initial error */ -#define GP_AXIAL_ERROR 0x8108 /* axial error increment */ -#define GP_DIAG_ERROR 0x810A /* diagonal error increment */ - -#define GP_SRC_COLOR_0 0x810C /* source color 0 */ -#define GP_SRC_COLOR_1 0x810E /* source color 1 */ -#define GP_PAT_COLOR_0 0x8110 /* pattern color 0 */ -#define GP_PAT_COLOR_1 0x8112 /* pattern color 1 */ -#define GP_PAT_COLOR_2 0x8114 /* pattern color 2 */ -#define GP_PAT_COLOR_3 0x8116 /* pattern color 3 */ -#define GP_PAT_DATA_0 0x8120 /* bits 31:0 of pattern */ -#define GP_PAT_DATA_1 0x8124 /* bits 63:32 of pattern */ -#define GP_PAT_DATA_2 0x8128 /* bits 95:64 of pattern */ -#define GP_PAT_DATA_3 0x812C /* bits 127:96 of pattern */ - -#define GP_RASTER_MODE 0x8200 /* raster operation */ -#define GP_VECTOR_MODE 0x8204 /* vector mode register */ -#define GP_BLIT_MODE 0x8208 /* blit mode register */ -#define GP_BLIT_STATUS 0x820C /* blit status register */ - -/* "GP_VECTOR_MODE" BIT DEFINITIONS */ - -#define VM_X_MAJOR 0x0000 /* X major vector */ -#define VM_Y_MAJOR 0x0001 /* Y major vector */ -#define VM_MAJOR_INC 0x0002 /* positive major axis step */ -#define VM_MINOR_INC 0x0004 /* positive minor axis step */ -#define VM_READ_DST_FB 0x0008 /* read destination data */ - -/* "GP_RASTER_MODE" BIT DEFINITIONS */ - -#define RM_PAT_DISABLE 0x0000 /* pattern is disabled */ -#define RM_PAT_MONO 0x0100 /* 1BPP pattern expansion */ -#define RM_PAT_DITHER 0x0200 /* 2BPP pattern expansion */ -#define RM_PAT_COLOR 0x0300 /* 8BPP or 16BPP pattern */ -#define RM_PAT_MASK 0x0300 /* mask for pattern mode */ -#define RM_PAT_TRANSPARENT 0x0400 /* transparent 1BPP pattern */ -#define RM_SRC_TRANSPARENT 0x0800 /* transparent 1BPP source */ - -/* "GP_BLIT_STATUS" BIT DEFINITIONS */ - -#define BS_BLIT_BUSY 0x0001 /* blit engine is busy */ -#define BS_PIPELINE_BUSY 0x0002 /* graphics pipeline is bus */ -#define BS_BLIT_PENDING 0x0004 /* blit pending */ -#define BC_8BPP 0x0000 /* 8BPP mode */ -#define BC_16BPP 0x0100 /* 16BPP mode */ -#define BC_FB_WIDTH_1024 0x0000 /* framebuffer width = 1024 */ -#define BC_FB_WIDTH_2048 0x0200 /* framebuffer width = 2048 */ - -/* "GP_BLIT_MODE" BIT DEFINITIONS */ - -#define BM_READ_SRC_NONE 0x0000 /* source foreground color */ -#define BM_READ_SRC_FB 0x0001 /* read source from FB */ -#define BM_READ_SRC_BB0 0x0002 /* read source from BB0 */ -#define BM_READ_SRC_BB1 0x0003 /* read source from BB1 */ -#define BM_READ_SRC_MASK 0x0003 /* read source mask */ - -#define BM_READ_DST_NONE 0x0000 /* no destination data */ -#define BM_READ_DST_BB0 0x0008 /* destination from BB0 */ -#define BM_READ_DST_BB1 0x000C /* destination from BB1 */ -#define BM_READ_DST_FB0 0x0010 /* dest from FB (store BB0) */ -#define BM_READ_DST_FB1 0x0014 /* dest from FB (store BB1)*/ -#define BM_READ_DST_MASK 0x001C /* read destination mask */ - -#define BM_WRITE_FB 0x0000 /* write to framebuffer */ -#define BM_WRITE_MEM 0x0020 /* write to memory */ -#define BM_WRITE_MASK 0x0020 /* write mask */ - -#define BM_SOURCE_COLOR 0x0000 /* source is 8BPP or 16BPP */ -#define BM_SOURCE_EXPAND 0x0040 /* source is 1BPP */ -#define BM_SOURCE_TEXT 0x00C0 /* source is 1BPP text */ -#define BM_SOURCE_MASK 0x00C0 /* source mask */ - -#define BM_REVERSE_Y 0x0100 /* reverse Y direction */ - -/* THE DRIVER NEEDS TO MAINTAIN THE SIZE AND LOCATION OF THE BLT BUFFERS -// These constants will work with 2K or 3K config, 8 or 16 BPP. The driver -// should set them, however, to optimize for the current config. Otherwise -// screen to screen BLTs, for example, may be visibly split into two vertical -// sections when they do not need to be. -*/ - -/* STATIC VARIABLES FOR GXRENDER.C FILE */ - -unsigned char *GXRregptr; -unsigned short GXRbpp; -unsigned short GXRbb0Base; -unsigned short GXRbb1Base; -unsigned short GXRbufferWidthPixels; - -unsigned short GXRpatternFlags; -unsigned short GXRsourceFlags; -unsigned short GXRsavedColor; -unsigned short GXRsavedRop; -unsigned short GXRusesDstData; - -/* MACROS FOR REGISTER ACCESS -// These macros asssume that a pointer was specified during initialization. -// They also assume 32-bit access is possible (16-bit access such as for -// Windows 98 display drivers would require different macros). -*/ - -#define WRITE_REG8(offset, value) \ - (*(volatile unsigned char *)(GXRregptr + (offset))) = (value) - -#define WRITE_REG16(offset, value) \ - (*(volatile unsigned short *)(GXRregptr + (offset))) = (value) - -#define WRITE_REG32(offset, value) \ - (*(volatile unsigned long *)(GXRregptr + (offset))) = (value) - -#define READ_REG16(offset) \ - (*(volatile unsigned short *)(GXRregptr + (offset))) - -#define READ_REG32(offset) \ - (*(volatile unsigned long *)(GXRregptr + (offset))) - -/* -//--------------------------------------------------------------------------- -// GXR_INITIALIZE -// -// This routine initializes the parameters for the current configuration. -// -// REGPTR pointer to GX memory mapped registers -// BPP bits per pixel (8 pr 16) -// -//--------------------------------------------------------------------------- -*/ - -void gxr_initialize(unsigned char *regptr, unsigned short bpp, - unsigned short BB0base, unsigned short BB1base, - unsigned short BBwidthPixels) -{ - GXRregptr = regptr; - GXRbpp = bpp; - GXRbb0Base = BB0base; - GXRbb1Base = BB1base; - GXRbufferWidthPixels = BBwidthPixels; -} - -/* -//--------------------------------------------------------------------------- -// GXR_WAIT_UNTIL_IDLE -// -// This routine waits until the graphics engine is idle. -//--------------------------------------------------------------------------- -*/ - -void gxr_wait_until_idle(void) -{ - while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_BUSY); -} - -/* -//--------------------------------------------------------------------------- -// GXR_LOAD_SOLID_SOURCE -// -// This routine is used to specify a solid source color. For the Xfree96 -// display driver, the source color is used to specify a planemask and the -// ROP is adjusted accordingly. -//--------------------------------------------------------------------------- -*/ - -void gxr_load_solid_source(unsigned short color) -{ - /* CLEAR TRANSPARENCY FLAG */ - - GXRsourceFlags = 0; - - /* FORMAT 8 BPP COLOR */ - /* GX requires 8BPP color data be duplicated into bits [15:8]. */ - - if (!(READ_REG16(GP_BLIT_STATUS) & BC_16BPP)) - { - color &= 0x00FF; - color |= (color << 8); - } - - /* POLL UNTIL ABLE TO WRITE THE SOURCE COLOR */ - - while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING); - WRITE_REG16(GP_SRC_COLOR_0, color); -} - -/* -//--------------------------------------------------------------------------- -// GXR_LOAD_MONO_SOURCE -// -// This routine is used to specify the monochrome source colors. -//--------------------------------------------------------------------------- -*/ - -void gxr_load_mono_source(unsigned short bgcolor, unsigned short fgcolor, - unsigned short transparent) -{ - /* SET TRANSPARENCY FLAG */ - - GXRsourceFlags = transparent ? RM_SRC_TRANSPARENT : 0; - - /* FORMAT 8 BPP COLOR */ - /* GX requires 8BPP color data be duplicated into bits [15:8]. */ - - if (!(READ_REG16(GP_BLIT_STATUS) & BC_16BPP)) - { - bgcolor &= 0x00FF; - bgcolor |= (bgcolor << 8); - fgcolor &= 0x00FF; - fgcolor |= (fgcolor << 8); - } - - /* POLL UNTIL ABLE TO WRITE THE SOURCE COLOR */ - - while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING); - WRITE_REG16(GP_SRC_COLOR_0, bgcolor); - WRITE_REG16(GP_SRC_COLOR_1, fgcolor); -} - -/* -//--------------------------------------------------------------------------- -// GXR_LOAD_SOLID_PATTERN -// -// This routine is used to specify a solid pattern color. It is called -// before performing solid rectangle fills or more complicated BLTs that -// use a solid pattern color. -// -// The driver should always call "gxr_load_raster_operation" after a call -// to this routine to make sure that the pattern flags are set appropriately. -//--------------------------------------------------------------------------- -*/ - -void gxr_load_solid_pattern(unsigned short color) -{ - /* SET PATTERN FLAGS */ - - GXRpatternFlags = 0; - - /* FORMAT 8 BPP COLOR */ - /* GX requires 8BPP color data be duplicated into bits [15:8]. */ - - if (!(READ_REG16(GP_BLIT_STATUS) & BC_16BPP)) - { - color &= 0x00FF; - color |= (color << 8); - } - - /* SAVE THE REFORMATTED COLOR FOR LATER */ - /* Used to call the "gxr_solid_fill" routine for special cases. */ - - GXRsavedColor = color; - - /* POLL UNTIL ABLE TO WRITE THE PATTERN COLOR */ - - while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING); - WRITE_REG16(GP_PAT_COLOR_0, color); -} - -/* -//--------------------------------------------------------------------------- -// GXR_LOAD_MONO_PATTERN -// -// This routine is used to specify a monochrome pattern. -//--------------------------------------------------------------------------- -*/ - -void gxr_load_mono_pattern(unsigned short bgcolor, unsigned short fgcolor, - unsigned long data0, unsigned long data1, unsigned char transparent) -{ - /* SET PATTERN FLAGS */ - - GXRpatternFlags = transparent ? RM_PAT_MONO | RM_PAT_TRANSPARENT : - RM_PAT_MONO; - - /* FORMAT 8 BPP COLOR */ - /* GX requires 8BPP color data be duplicated into bits [15:8]. */ - - if (!(READ_REG16(GP_BLIT_STATUS) & BC_16BPP)) - { - bgcolor &= 0x00FF; - bgcolor |= (bgcolor << 8); - fgcolor &= 0x00FF; - fgcolor |= (fgcolor << 8); - } - - /* POLL UNTIL ABLE TO WRITE THE PATTERN COLORS AND DATA */ - - while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING); - WRITE_REG16(GP_PAT_COLOR_0, bgcolor); - WRITE_REG16(GP_PAT_COLOR_1, fgcolor); - WRITE_REG32(GP_PAT_DATA_0, data0); - WRITE_REG32(GP_PAT_DATA_1, data1); -} - -/* -//--------------------------------------------------------------------------- -// GXR_LOAD_RASTER_OPERATION -// -// This routine loads the specified raster operation. It sets the pattern -// flags appropriately. -//--------------------------------------------------------------------------- -*/ - -void gxr_load_raster_operation(unsigned char rop) -{ - unsigned short rop16; - - /* GENERATE 16-BIT VERSION OF ROP WITH PATTERN FLAGS */ - - rop16 = (unsigned short) rop | GXRpatternFlags; - if ((rop & 0x33) ^ ((rop >> 2) & 0x33)) - rop16 |= GXRsourceFlags; - - /* SAVE ROP FOR LATER COMPARISONS */ - /* Need to have the pattern flags included */ - - GXRsavedRop = rop16; - - /* SET FLAG INDICATING ROP REQUIRES DESTINATION DATA */ - /* True if even bits (0:2:4:6) do not equal the correspinding */ - /* even bits (1:3:5:7). */ - - GXRusesDstData = ((rop & 0x55) ^ ((rop >> 1) & 0x55)); - - /* POLL UNTIL ABLE TO WRITE THE PATTERN COLOR */ - /* Only one operation can be pending at a time. */ - - while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING); - WRITE_REG16(GP_RASTER_MODE, rop16); -} - -/* -//--------------------------------------------------------------------------- -// GXR_SOLID_FILL -// -// This routine MUST be used when performing a solid rectangle fill with -// the ROPs of PATCOPY (0xF0), BLACKNESS (0x00), WHITENESS (0xFF), or -// PATINVERT (0x0F). There is a bug in GXm for these cases that requires a -// workaround. -// -// For BLACKNESS (ROP = 0x00), set the color to 0x0000. -// For WHITENESS (ROP = 0xFF), set the color to 0xFFFF. -// For PATINVERT (ROP = 0x0F), invert the desired color. -// -// X screen X position (left) -// Y screen Y position (top) -// WIDTH width of rectangle, in pixels -// HEIGHT height of rectangle, in scanlines -// COLOR fill color -// -// THIS ROUTINE SHOULD NOT BE DIRECTLY CALLED FROM THE DRIVER. The driver -// should always use gxr_pattern_fill and let that routine call this one -// when approipriate. This is to hide quirks specific to MediaGX hardware. -//--------------------------------------------------------------------------- -*/ - -void gxr_solid_fill(unsigned short x, unsigned short y, - unsigned short width, unsigned short height, unsigned short color) -{ - unsigned short section; - - /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ - /* Only one operation can be pending at a time. */ - - while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING); - - /* SET REGISTERS TO DRAW RECTANGLE */ - - WRITE_REG16(GP_DST_XCOOR, x); - WRITE_REG16(GP_DST_YCOOR, y); - WRITE_REG16(GP_HEIGHT, height); - WRITE_REG16(GP_RASTER_MODE, 0x00F0); /* PATCOPY */ - WRITE_REG16(GP_PAT_COLOR_0, color); - - /* CHECK WIDTH FOR GX BUG WORKAROUND */ - - if (width <= 16) - { - /* OK TO DRAW SMALL RECTANGLE IN ONE PASS */ - - WRITE_REG16(GP_WIDTH, width); - WRITE_REG16(GP_BLIT_MODE, 0); - } - else - { - /* DRAW FIRST PART OF RECTANGLE */ - /* Get to a 16 pixel boundary. */ - - section = 0x10 - (x & 0x0F); - WRITE_REG16(GP_WIDTH, section); - WRITE_REG16(GP_BLIT_MODE, 0); - - /* POLL UNTIL ABLE TO LOAD THE SECOND RECTANGLE */ - - while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING); - WRITE_REG16(GP_DST_XCOOR, x + section); - WRITE_REG16(GP_DST_YCOOR, y); - WRITE_REG16(GP_WIDTH, width - section); - WRITE_REG16(GP_BLIT_MODE, 0); - } -} - -/* -//---------------------------------------------------------------------------- -// GXR_PATTERN_FILL -// -// This routine is used to fill a rectangular region. The pattern must -// be previously loaded using one of gxr_load_*_pattern routines. Also, the -// raster operation must be previously specified using the -// "gxr_load_raster_operation" routine. -// -// X screen X position (left) -// Y screen Y position (top) -// WIDTH width of rectangle, in pixels -// HEIGHT height of rectangle, in scanlines -//---------------------------------------------------------------------------- -*/ - -void gxr_pattern_fill(unsigned short x, unsigned short y, - unsigned short width, unsigned short height) -{ - unsigned short section, buffer_width, blit_mode; - - /* CHECK IF OPTIMIZED SOLID CASES */ - /* Check all 16 bits of the ROP to include solid pattern flags. */ - - switch(GXRsavedRop) - { - /* CHECK FOR SPECIAL CASES WITHOUT DESTINATION DATA */ - /* Need hardware workaround for fast "burst write" cases. */ - - case 0x00F0: - gxr_solid_fill(x, y, width, height, GXRsavedColor); - break; - case 0x000F: - gxr_solid_fill(x, y, width, height, ~GXRsavedColor); - break; - case 0x0000: - gxr_solid_fill(x, y, width, height, 0x0000); - break; - case 0x00FF: - gxr_solid_fill(x, y, width, height, 0xFFFF); - break; - - /* REMAINING CASES REQUIRE DESTINATION DATA OR NOT SOLID COLOR */ - - default: - - /* DETERMINE BLT MODE VALUE */ - /* Still here for non-solid patterns without destination data. */ - - blit_mode = GXRusesDstData ? BM_READ_DST_FB0 : 0; - - /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ - /* Write the registers that do not change for each section. */ - - while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING); - WRITE_REG16(GP_HEIGHT, height); - - /* SINCE ONLY DESTINATION DATA, WE CAN USE BOTH BB0 AND BB1. */ - /* Therefore, width available = BLT buffer width * 2. */ - - buffer_width = GXRbufferWidthPixels << 1; - - /* REPEAT UNTIL FINISHED WITH RECTANGLE */ - /* Perform BLT in vertical sections, as wide as the BLT buffer */ - /* allows. Hardware does not split the operations, so */ - /* software must do it to avoid large scanlines that would */ - /* overflow the BLT buffers. */ - - while(width > 0) - { - /* DETERMINE WIDTH OF SECTION */ - - if (width > buffer_width) section = buffer_width; - else section = width; - - /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ - - while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING); - WRITE_REG16(GP_DST_XCOOR, x); - WRITE_REG16(GP_DST_YCOOR, y); - WRITE_REG16(GP_WIDTH, section); - WRITE_REG16(GP_BLIT_MODE, blit_mode); - - /* ADJUST PARAMETERS FOR NEXT SECTION */ - - width -= section; - x += section; - } - break; - } -} - -/* -//---------------------------------------------------------------------------- -// SCREEN TO SCREEN BLT -// -// This routine should be used to perform a screen to screen BLT when the -// ROP does not require destination data. -// -// SRCX screen X position to copy from -// SRCY screen Y position to copy from -// DSTX screen X position to copy to -// DSTY screen Y position to copy to -// WIDTH width of rectangle, in pixels -// HEIGHT height of rectangle, in scanlines -//---------------------------------------------------------------------------- -*/ - -void gxr_screen_to_screen_blt(unsigned short srcx, unsigned short srcy, - unsigned short dstx, unsigned short dsty, unsigned short width, - unsigned short height) -{ - unsigned short section, buffer_width; - unsigned short blit_mode; - - /* CHECK IF RASTER OPERATION REQUIRES DESTINATION DATA */ - - blit_mode = GXRusesDstData ? BM_READ_DST_FB1 | BM_READ_SRC_FB : - BM_READ_SRC_FB; - - /* CHECK Y DIRECTION */ - /* Hardware has support for negative Y direction. */ - - if (dsty > srcy) - { - blit_mode |= BM_REVERSE_Y; - srcy += height - 1; - dsty += height - 1; - } - - /* CHECK X DIRECTION */ - /* Hardware does not support negative X direction since at the time */ - /* of development all supported resolutions could fit a scanline of */ - /* data at once into the BLT buffers (using both BB0 and BB1). This */ - /* code is more generic to allow for any size BLT buffer. */ - - if (dstx > srcx) - { - srcx += width; - dstx += width; - } - - /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ - /* Write the registers that do not change for each section. */ - - while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING); - WRITE_REG16(GP_HEIGHT, height); - - /* CHECK AVAILABLE BLT BUFFER SIZE */ - /* Can use both BLT buffers if no destination data is required. */ - - buffer_width = GXRusesDstData ? GXRbufferWidthPixels : - GXRbufferWidthPixels << 1; - - /* REPEAT UNTIL FINISHED WITH RECTANGLE */ - /* Perform BLT in vertical sections, as wide as the BLT buffer allows. */ - /* Hardware does not split the operations, so software must do it to */ - /* avoid large scanlines that would overflow the BLT buffers. */ - - while(width > 0) - { - /* CHECK WIDTH OF CURRENT SECTION */ - - if (width > buffer_width) section = buffer_width; - else section = width; - - /* PROGRAM REGISTERS THAT ARE THE SAME FOR EITHER X DIRECTION */ - - while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING); - WRITE_REG16(GP_SRC_YCOOR, srcy); - WRITE_REG16(GP_DST_YCOOR, dsty); - WRITE_REG16(GP_WIDTH, section); - - /* CHECK X DIRECTION */ - - if (dstx > srcx) - { - /* NEGATIVE X DIRECTION */ - /* Still positive X direction within the section. */ - - srcx -= section; - dstx -= section; - WRITE_REG16(GP_SRC_XCOOR, srcx); - WRITE_REG16(GP_DST_XCOOR, dstx); - WRITE_REG16(GP_BLIT_MODE, blit_mode); - } - else - { - /* POSITIVE X DIRECTION */ - - WRITE_REG16(GP_SRC_XCOOR, srcx); - WRITE_REG16(GP_DST_XCOOR, dstx); - WRITE_REG16(GP_BLIT_MODE, blit_mode); - dstx += section; - srcx += section; - } - width -= section; - } -} - -/* -//---------------------------------------------------------------------------- -// SCREEN TO SCREEN TRANSPARENT BLT -// -// This routine should be used to perform a screen to screen BLT when a -// specified color should by transparent. The only supported ROP is SRCCOPY. -// -// SRCX screen X position to copy from -// SRCY screen Y position to copy from -// DSTX screen X position to copy to -// DSTY screen Y position to copy to -// WIDTH width of rectangle, in pixels -// HEIGHT height of rectangle, in scanlines -// COLOR transparent color -//---------------------------------------------------------------------------- -*/ - -void gxr_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy, - unsigned short dstx, unsigned short dsty, unsigned short width, - unsigned short height, unsigned short color) -{ - unsigned short section, buffer_width; - unsigned short blit_mode = BM_READ_SRC_FB; - unsigned short i; - - /* CHECK Y DIRECTION */ - /* Hardware has support for negative Y direction. */ - - if (dsty > srcy) - { - blit_mode |= BM_REVERSE_Y; - srcy += height - 1; - dsty += height - 1; - } - - /* CHECK X DIRECTION */ - /* Hardware does not support negative X direction since at the time */ - /* of development all supported resolutions could fit a scanline of */ - /* data at once into the BLT buffers (using both BB0 and BB1). This */ - /* code is more generic to allow for any size BLT buffer. */ - - if (dstx > srcx) - { - srcx += width; - dstx += width; - } - - /* CALCULATE BLT BUFFER SIZE */ - /* Need to use BB1 to store the BLT buffer data. */ - - buffer_width = GXRbufferWidthPixels; - - /* WRITE TRANSPARENCY COLOR TO BLT BUFFER 1 */ - - if (!(READ_REG16(GP_BLIT_STATUS) & BC_16BPP)) - { - color &= 0x00FF; - color |= (color << 8); - } - - /* WAIT UNTIL PIPELINE IS NOT BUSY BEFORE LOADING DATA INTO BB1 */ - /* Need to make sure any previous BLT using BB1 is complete. */ - - while(READ_REG16(GP_BLIT_STATUS) & BS_PIPELINE_BUSY); - for (i = 0; i < 16; i+=2) - { - WRITE_REG16(GXRbb1Base+i, color); - } - - /* DO BOGUS BLT TO LATCH DATA FROM BB1 */ - /* Already know graphics pipeline is idle. */ - - WRITE_REG32(GP_DST_XCOOR, 0); - WRITE_REG32(GP_SRC_XCOOR, 0); - WRITE_REG16(GP_WIDTH, 16); - WRITE_REG16(GP_HEIGHT, 1); - WRITE_REG16(GP_RASTER_MODE, 0x00CC); - WRITE_REG16(GP_BLIT_MODE, BM_READ_SRC_FB | BM_READ_DST_BB1); - - /* WRITE REGISTERS FOR REAL SCREEN TO SCREEN BLT */ - - while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING); - WRITE_REG16(GP_HEIGHT, height); - WRITE_REG16(GP_RASTER_MODE, 0x10C6); - WRITE_REG32(GP_PAT_COLOR_0, 0xFFFFFFFF); - - /* REPEAT UNTIL FINISHED WITH RECTANGLE */ - /* Perform BLT in vertical sections, as wide as the BLT buffer allows. */ - /* Hardware does not split the operations, so software must do it to */ - /* avoid large scanlines that would overflow the BLT buffers. */ - - while(width > 0) - { - /* CHECK WIDTH OF CURRENT SECTION */ - - if (width > buffer_width) section = buffer_width; - else section = width; - - /* PROGRAM REGISTERS THAT ARE THE SAME FOR EITHER X DIRECTION */ - - while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING); - WRITE_REG16(GP_SRC_YCOOR, srcy); - WRITE_REG16(GP_DST_YCOOR, dsty); - WRITE_REG16(GP_WIDTH, section); - - /* CHECK X DIRECTION */ - /* Again, this must be done in software, and can be removed if the */ - /* display driver knows that the BLT buffers will always be large */ - /* enough to contain an entire scanline of a screen to screen BLT. */ - - if (dstx > srcx) - { - /* NEGATIVE X DIRECTION */ - /* Still positive X direction within the section. */ - - srcx -= section; - dstx -= section; - WRITE_REG16(GP_SRC_XCOOR, srcx); - WRITE_REG16(GP_DST_XCOOR, dstx); - WRITE_REG16(GP_BLIT_MODE, blit_mode); - } - else - { - /* POSITIVE X DIRECTION */ - - WRITE_REG16(GP_SRC_XCOOR, srcx); - WRITE_REG16(GP_DST_XCOOR, dstx); - WRITE_REG16(GP_BLIT_MODE, blit_mode); - dstx += section; - srcx += section; - } - width -= section; - } -} - -/* -//---------------------------------------------------------------------------- -// COLOR BITMAP TO SCREEN BLT -// -// This routine transfers color bitmap data to the screen. For most cases, -// when the ROP is SRCCOPY, it may be faster to write a separate routine that -// copies the data to the frame buffer directly. This routine should be -// used when the ROP requires destination data. -// -// Transparency is handled by another routine. -// -// SRCX X offset within source bitmap -// SRCY Y offset within source bitmap -// DSTX screen X position to render data -// DSTY screen Y position to render data -// WIDTH width of rectangle, in pixels -// HEIGHT height of rectangle, in scanlines -// *DATA pointer to bitmap data -// PITCH pitch of bitmap data (bytes between scanlines) -// ROP ternary raster operation (0x00-0xFF). -//---------------------------------------------------------------------------- -*/ - -void gxr_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, - unsigned short dstx, unsigned short dsty, unsigned short width, - unsigned short height, unsigned char *data, unsigned short pitch, - unsigned char rop) -{ - unsigned short section, buffer_width; - unsigned short blit_mode = BM_READ_SRC_BB0; - unsigned short line_srcx, line_dstx, line_width; - unsigned short offset, i; - - /* CHECK IF ROP REQUIRES DESTINATION DATA */ - /* Even bits (0:2:4:6) do not equal corresponding odd bits (1:3:5:7). */ - - if ((rop & 0x55) ^ ((rop >> 1) & 0x55)) - blit_mode |= BM_READ_DST_FB1; - - /* CHECK SIZE OF BLT BUFFER */ - - buffer_width = GXRbufferWidthPixels; - - /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ - /* Write the registers that do not change for each section. */ - - while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING); - WRITE_REG16(GP_HEIGHT, 1); - WRITE_REG16(GP_RASTER_MODE, (unsigned short) rop & 0x00FF); - - /* REPEAT FOR EACH SCANLINE */ - - offset = srcy * pitch; - - while(height > 0) - { - line_width = width; - line_srcx = srcx; - line_dstx = dstx; - - while(line_width > 0) - { - /* CHECK WIDTH OF CURRENT SECTION */ - - if (line_width > buffer_width) section = buffer_width; - else section = line_width; - - /* TRANSFER SCANLINE OF BITMAP DATA TO BLT BUFFER 0 */ - /* Need to wait for BS_PIPELINE_BUSY to make sure that the */ - /* data in BB0 for the previous scanline is no longer used. */ - /* This can be heavily optimized to not do a byte at a time. */ - - while(READ_REG16(GP_BLIT_STATUS) & BS_PIPELINE_BUSY); - if (READ_REG16(GP_BLIT_STATUS) & BC_16BPP) - { - for (i = 0; i < section; i++) - { - WRITE_REG16(GXRbb0Base+i, data[offset+((line_srcx+i)<<1)]); - } - } - else - { - for (i = 0; i < section; i++) - { - WRITE_REG8(GXRbb0Base+i, data[line_srcx+offset+i]); - } - } - - /* RENDER FROM BB0 TO FRAME BUFFER */ - - while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING); - WRITE_REG16(GP_DST_XCOOR, line_dstx); - WRITE_REG16(GP_DST_YCOOR, dsty); - WRITE_REG16(GP_WIDTH, section); - WRITE_REG16(GP_BLIT_MODE, blit_mode); - - line_width -= section; - line_dstx += section; - line_srcx += section; - } - height--; - dsty++; - offset += pitch; - } -} - -/* -//---------------------------------------------------------------------------- -// COLOR BITMAP TO SCREEN TRANSPARENT BLT -// -// This routine transfers color bitmap data to the screen with transparency. -// The transparent color is specified. The only supported ROP is SRCCOPY, -// meaning that transparency cannot be applied if the ROP requires -// destination data (this is a hardware restriction). -// -// SRCX X offset within source bitmap -// SRCY Y offset within source bitmap -// DSTX screen X position to render data -// DSTY screen Y position to render data -// WIDTH width of rectangle, in pixels -// HEIGHT height of rectangle, in scanlines -// *DATA pointer to bitmap data -// PITCH pitch of bitmap data (bytes between scanlines) -// COLOR transparent color -//---------------------------------------------------------------------------- -*/ - -void gxr_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy, - unsigned short dstx, unsigned short dsty, unsigned short width, - unsigned short height, unsigned char *data, unsigned short pitch, - unsigned short color) -{ - unsigned short section, buffer_width; - unsigned short blit_mode = BM_READ_SRC_BB0; - unsigned short line_srcx, line_dstx, line_width; - unsigned short offset, i, first_blt = 1; - - /* CHECK SIZE OF BLT BUFFER */ - - buffer_width = GXRbufferWidthPixels; - - /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ - /* Write the registers that do not change for each section. */ - - while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING); - WRITE_REG16(GP_HEIGHT, 1); - WRITE_REG16(GP_RASTER_MODE, 0x10C6); - WRITE_REG32(GP_PAT_COLOR_0, 0xFFFFFFFF); - - /* CALCULATE OFFSET INTO BITMAP DATA */ - - offset = srcy * pitch; - - /* REPEAT FOR EACH SCANLINE */ - - while(height > 0) - { - line_width = width; - line_srcx = srcx; - line_dstx = dstx; - - while(line_width > 0) - { - /* CHECK WIDTH OF CURRENT SECTION */ - - if (line_width > buffer_width) section = buffer_width; - else section = line_width; - - /* TRANSFER SCANLINE OF BITMAP DATA TO BLT BUFFER 0 */ - /* Need to wait for BS_PIPELINE_BUSY to make sure that the */ - /* data in BB0 for the previous scanline is no longer used. */ - /* This can be heavily optimized to not do a byte at a time. */ - - while(READ_REG16(GP_BLIT_STATUS) & BS_PIPELINE_BUSY); - if (READ_REG16(GP_BLIT_STATUS) & BC_16BPP) - { - for (i = 0; i < section; i++) - { - WRITE_REG16(GXRbb0Base+i, data[offset+((line_srcx+i)<<1)]); - } - } - else - { - for (i = 0; i < section; i++) - { - WRITE_REG8(GXRbb0Base+i, data[line_srcx+offset+i]); - } - } - - /* RENDER FROM BB0 TO FRAME BUFFER */ - - while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING); - WRITE_REG16(GP_DST_XCOOR, line_dstx); - WRITE_REG16(GP_DST_YCOOR, dsty); - WRITE_REG16(GP_WIDTH, section); - - /* NEED TO DO EXTRA WORK FOR THE FIRST BLT */ - - if (first_blt) - { - /* WRITE TRANSPARENCY COLOR TO BLT BUFFER 1 */ - /* This can be heavily optimized to not do 16-bits at a time. */ - - if (READ_REG16(GP_BLIT_STATUS) & BC_16BPP) - { - for (i = 0; i < section; i++) - { - WRITE_REG16(GXRbb1Base+i*2, color); - } - } - else - { - for (i = 0; i < section; i++) - { - WRITE_REG8(GXRbb1Base+i, (unsigned char) color); - } - } - WRITE_REG16(GP_BLIT_MODE, BM_READ_SRC_BB0 | BM_READ_DST_BB1); - first_blt = 0; - } - else - { - /* AFTER FIRST BLT, THE TRANSPARENCY DATA IS LATCHED */ - /* Save time by not reading data from BB1. */ - - WRITE_REG16(GP_BLIT_MODE, BM_READ_SRC_BB0); - } - line_width -= section; - line_dstx += section; - line_srcx += section; - } - height--; - dsty++; - offset += pitch; - } -} - -/* -//---------------------------------------------------------------------------- -// MONOCHROME BITMAP TO SCREEN BLT -// -// This routine transfers monochrome bitmap data to the screen. -// -// SRCX X offset within source bitmap -// SRCY Y offset within source bitmap -// DSTX screen X position to render data -// DSTY screen Y position to render data -// WIDTH width of rectangle, in pixels -// HEIGHT height of rectangle, in scanlines -// *DATA pointer to bitmap data -// PITCH pitch of bitmap data (bytes between scanlines) -// FGCOLOR color for bits = 1 -// BGCOLOR color for bits = 0 -// ROP ternary raster operation (0x00-0xFF). -// TRANSPARENT zero for opaque, otherwise transparent -//---------------------------------------------------------------------------- -*/ - -void gxr_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, - unsigned short dstx, unsigned short dsty, unsigned short width, - unsigned short height, unsigned char *data, unsigned short pitch, - unsigned short fgcolor, unsigned short bgcolor, unsigned char rop, - unsigned char transparent) -{ - unsigned short section, buffer_width; - unsigned short blit_mode = BM_READ_SRC_BB0 | BM_SOURCE_EXPAND; - unsigned short line_srcx, line_dstx, line_width; - unsigned short offset, i, bytes, raster_mode; - - /* FORMAT 8BPP COLOR */ - /* GX requires that 8BPP color data be duplicated into bits [15:8]. */ - - if (!(READ_REG16(GP_BLIT_STATUS) & BC_16BPP)) - { - fgcolor &= 0x00FF; - fgcolor |= (fgcolor << 8); - bgcolor &= 0x00FF; - bgcolor |= (bgcolor << 8); - } - - /* CHECK IF ROP REQUIRES DESTINATION DATA */ - /* Even bits (0:2:4:6) do not equal corresponding odd bits (1:3:5:7). */ - - if ((rop & 0x55) ^ ((rop >> 1) & 0x55)) - blit_mode |= BM_READ_DST_FB1; - - /* CALCULATE RASTER MODE */ - /* Set mono flag. Transparency set based on input parameter. */ - - raster_mode = ((unsigned short) rop & 0x00FF); - if (transparent) raster_mode |= RM_SRC_TRANSPARENT; - - /* CHECK SIZE OF BLT BUFFER */ - - buffer_width = GXRbufferWidthPixels; - - /* CALCULATE OFFSET INTO BITMAP DATA */ - - offset = srcy * pitch; - - /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ - /* Write the registers that do not change for each section. */ - - while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING); - WRITE_REG16(GP_HEIGHT, 1); - WRITE_REG16(GP_RASTER_MODE, raster_mode); - WRITE_REG16(GP_SRC_COLOR_0, bgcolor); - WRITE_REG16(GP_SRC_COLOR_1, fgcolor); - - /* REPEAT FOR EACH SCANLINE */ - - while(height > 0) - { - line_width = width; - line_srcx = srcx; - line_dstx = dstx; - - while(line_width > 0) - { - /* CHECK WIDTH OF CURRENT SECTION */ - /* Only divide into sections if reading destination data. */ - /* Since the source data is monochrome, it will always fit. */ - - section = line_width; - if ((line_width > buffer_width) && (blit_mode & BM_READ_DST_FB1)) - section = buffer_width; - - /* BYTES TO TRANSFER */ - /* Add two bytes to handle truncating and alignment. */ - - bytes = (section >> 3) + 2; - - /* TRANSFER SCANLINE OF BITMAP DATA TO BLT BUFFER 0 */ - /* Need to wait for BS_PIPELINE_BUSY to make sure that the */ - /* data in BB0 for the previous scanline is no longer used. */ - /* This can be heavily optimized to not do a byte at a time. */ - - while(READ_REG16(GP_BLIT_STATUS) & BS_PIPELINE_BUSY); - for (i = 0; i < bytes; i++) - { - WRITE_REG8(GXRbb0Base+i, data[(line_srcx >> 3)+offset+i]); - } - - /* RENDER FROM BB0 TO FRAME BUFFER */ - - while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING); - WRITE_REG16(GP_DST_XCOOR, line_dstx); - WRITE_REG16(GP_DST_YCOOR, dsty); - WRITE_REG16(GP_SRC_XCOOR, line_srcx & 7); - WRITE_REG16(GP_WIDTH, section); - WRITE_REG16(GP_BLIT_MODE, blit_mode); - - line_width -= section; - line_dstx += section; - line_srcx += section; - } - height--; - dsty++; - offset += pitch; - } -} - -/* -//---------------------------------------------------------------------------- -// TEXT GLYPH -// -// This routine draws a single character of text. It can only be used for -// characters that are less than or equal to 64x64 in size, since it -// transfers the entire data into the BLT buffers at once. Larger characters -// should use the monochrome bitmap to screen routine. The only supported -// ROP is SRCCOPY, again since the BLT buffer size is limited. -// -// SRCX X offset within source bitmap -// SRCY Y offset within source bitmap -// DSTX screen X position to render data -// DSTY screen Y position to render data -// WIDTH width of rectangle, in pixels -// HEIGHT height of rectangle, in scanlines -// *DATA pointer to bitmap data (NULL if already loaded) -// PITCH pitch of bitmap data (bytes between scanlines) -// -// For the Xfree86 display driver, the OS is given a pointer to BB0. -// Therefore, the data is already loaded when the driver is called, so the -// driver simply passes a NULL pointer to this routine. -// -// This same type of routine could be developed for "icons", or small -// color bitmaps that can fit entirely in the BLT buffer. -//---------------------------------------------------------------------------- -*/ - -void gxr_text_glyph(unsigned short srcx, unsigned short srcy, - unsigned short dstx, unsigned short dsty, unsigned short width, - unsigned short height, unsigned char *data, unsigned short pitch) -{ - unsigned short offset, i, j, buffer_offset, bytes, blit_mode; - - blit_mode = BM_READ_SRC_BB0 | BM_SOURCE_EXPAND; - if (GXRusesDstData) blit_mode |= BM_READ_DST_FB1; - - /* CHECK IF DATA NEEDS TO BE TRANSFERRED */ - - if (data != 0) - { - /* TRANSFER ENTIRE BITMAP DATA TO BLT BUFFER 0 */ - /* Need to wait for BS_PIPELINE_BUSY to make sure that the */ - /* data in BB0 for any previous BLT is no longer used. */ - /* This data transfer has lots of room for performance optimization. */ - - buffer_offset = 0; - offset = srcy * pitch + (srcx >> 3); - bytes = ((width + (srcx & 7) + 7) >> 3); - while(READ_REG16(GP_BLIT_STATUS) & BS_PIPELINE_BUSY); - for (j = 0; j < height; j++) - { - for (i = 0; i < bytes; i++) - { - WRITE_REG8(GXRbb0Base+buffer_offset, data[offset+i]); - buffer_offset++; - } - offset += pitch; - } - } - - /* RENDER FROM BB0 TO FRAME BUFFER */ - /* Already know that the pipeline is idle from loading data. */ - - WRITE_REG16(GP_DST_XCOOR, dstx); - WRITE_REG16(GP_DST_YCOOR, dsty); - WRITE_REG16(GP_SRC_XCOOR, srcx & 7); - WRITE_REG16(GP_WIDTH, width); - WRITE_REG16(GP_HEIGHT, height); - WRITE_REG16(GP_BLIT_MODE, blit_mode); -} - -/* -//---------------------------------------------------------------------------- -// BRESENHAM LINE -// -// This routine draws a vector using the specified Bresenham parameters. -// Currently this file does not support a routine that accepts the two -// endpoints of a vector and calculates the Bresenham parameters. If it -// ever does, this routine is still required for vectors that have been -// clipped. -// -// X screen X position to start vector -// Y screen Y position to start vector -// LENGTH length of the vector, in pixels -// INITERR Bresenham initial error term -// AXIALERR Bresenham axial error term -// DIAGERR Bresenham diagonal error term -// FLAGS VM_YMAJOR, VM_MAJOR_INC, VM_MINOR_INC -//---------------------------------------------------------------------------- -*/ - -void gxr_bresenham_line(unsigned short x, unsigned short y, - unsigned short length, unsigned short initerr, - unsigned short axialerr, unsigned short diagerr, - unsigned short flags) -{ - unsigned short vector_mode = flags; - if (GXRusesDstData) vector_mode |= VM_READ_DST_FB; - - /* CHECK NULL LENGTH */ - - if (!length) return; - - /* LOAD THE REGISTERS FOR THE VECTOR */ - - while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING); - WRITE_REG16(GP_DST_XCOOR, x); - WRITE_REG16(GP_DST_YCOOR, y); - WRITE_REG16(GP_VECTOR_LENGTH, length); - WRITE_REG16(GP_INIT_ERROR, initerr); - WRITE_REG16(GP_AXIAL_ERROR, axialerr); - WRITE_REG16(GP_DIAG_ERROR, diagerr); - WRITE_REG16(GP_VECTOR_MODE, vector_mode); -} - -/* END OF FILE */ -