171d7fec4Smrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/rndr_gu1.c,v 1.2 2003/01/14 09:34:34 alanh Exp $ */ 271d7fec4Smrg/* 371d7fec4Smrg * $Workfile: rndr_gu1.c $ 471d7fec4Smrg * 571d7fec4Smrg * This file contains routines to program the 2D acceleration hardware for 671d7fec4Smrg * the first generation graphics unit (GXLV, SC1200). 771d7fec4Smrg * 871d7fec4Smrg * gfx_set_bpp 971d7fec4Smrg * gfx_set_solid_pattern 1071d7fec4Smrg * gfx_set_mono_pattern 1171d7fec4Smrg * gfx_set_color_pattern 1271d7fec4Smrg * gfx_set_solid_source 1371d7fec4Smrg * gfx_set_mono_source 1471d7fec4Smrg * gfx_set_raster_operation 1571d7fec4Smrg * gfx_pattern_fill 1671d7fec4Smrg * gfx_screen_to_screen_blt 1771d7fec4Smrg * gfx_screen_to_screen_xblt 1871d7fec4Smrg * gfx_color_bitmap_to_screen_blt 1971d7fec4Smrg * gfx_color_bitmap_to_screen_xblt 2071d7fec4Smrg * gfx_mono_bitmap_to_screen_blt 2171d7fec4Smrg * gfx_bresenham_line 2271d7fec4Smrg * gfx_wait_until_idle 2371d7fec4Smrg * 2471d7fec4Smrg * NSC_LIC_ALTERNATIVE_PREAMBLE 2571d7fec4Smrg * 2671d7fec4Smrg * Revision 1.0 2771d7fec4Smrg * 2871d7fec4Smrg * National Semiconductor Alternative GPL-BSD License 2971d7fec4Smrg * 3071d7fec4Smrg * National Semiconductor Corporation licenses this software 3171d7fec4Smrg * ("Software"): 3271d7fec4Smrg * 3371d7fec4Smrg * Durango 3471d7fec4Smrg * 3571d7fec4Smrg * under one of the two following licenses, depending on how the 3671d7fec4Smrg * Software is received by the Licensee. 3771d7fec4Smrg * 3871d7fec4Smrg * If this Software is received as part of the Linux Framebuffer or 3971d7fec4Smrg * other GPL licensed software, then the GPL license designated 4071d7fec4Smrg * NSC_LIC_GPL applies to this Software; in all other circumstances 4171d7fec4Smrg * then the BSD-style license designated NSC_LIC_BSD shall apply. 4271d7fec4Smrg * 4371d7fec4Smrg * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ 4471d7fec4Smrg 4571d7fec4Smrg/* NSC_LIC_BSD 4671d7fec4Smrg * 4771d7fec4Smrg * National Semiconductor Corporation Open Source License for Durango 4871d7fec4Smrg * 4971d7fec4Smrg * (BSD License with Export Notice) 5071d7fec4Smrg * 5171d7fec4Smrg * Copyright (c) 1999-2001 5271d7fec4Smrg * National Semiconductor Corporation. 5371d7fec4Smrg * All rights reserved. 5471d7fec4Smrg * 5571d7fec4Smrg * Redistribution and use in source and binary forms, with or without 5671d7fec4Smrg * modification, are permitted provided that the following conditions 5771d7fec4Smrg * are met: 5871d7fec4Smrg * 5971d7fec4Smrg * * Redistributions of source code must retain the above copyright 6071d7fec4Smrg * notice, this list of conditions and the following disclaimer. 6171d7fec4Smrg * 6271d7fec4Smrg * * Redistributions in binary form must reproduce the above 6371d7fec4Smrg * copyright notice, this list of conditions and the following 6471d7fec4Smrg * disclaimer in the documentation and/or other materials provided 6571d7fec4Smrg * with the distribution. 6671d7fec4Smrg * 6771d7fec4Smrg * * Neither the name of the National Semiconductor Corporation nor 6871d7fec4Smrg * the names of its contributors may be used to endorse or promote 6971d7fec4Smrg * products derived from this software without specific prior 7071d7fec4Smrg * written permission. 7171d7fec4Smrg * 7271d7fec4Smrg * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 7371d7fec4Smrg * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 7471d7fec4Smrg * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 7571d7fec4Smrg * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 7671d7fec4Smrg * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY 7771d7fec4Smrg * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 7871d7fec4Smrg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 7971d7fec4Smrg * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 8071d7fec4Smrg * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 8171d7fec4Smrg * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, 8271d7fec4Smrg * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY 8371d7fec4Smrg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 8471d7fec4Smrg * OF SUCH DAMAGE. 8571d7fec4Smrg * 8671d7fec4Smrg * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF 8771d7fec4Smrg * YOUR JURISDICTION. It is licensee's responsibility to comply with 8871d7fec4Smrg * any export regulations applicable in licensee's jurisdiction. Under 8971d7fec4Smrg * CURRENT (2001) U.S. export regulations this software 9071d7fec4Smrg * is eligible for export from the U.S. and can be downloaded by or 9171d7fec4Smrg * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed 9271d7fec4Smrg * destinations which include Cuba, Iraq, Libya, North Korea, Iran, 9371d7fec4Smrg * Syria, Sudan, Afghanistan and any other country to which the U.S. 9471d7fec4Smrg * has embargoed goods and services. 9571d7fec4Smrg * 9671d7fec4Smrg * END_NSC_LIC_BSD */ 9771d7fec4Smrg 9871d7fec4Smrg/* NSC_LIC_GPL 9971d7fec4Smrg * 10071d7fec4Smrg * National Semiconductor Corporation Gnu General Public License for Durango 10171d7fec4Smrg * 10271d7fec4Smrg * (GPL License with Export Notice) 10371d7fec4Smrg * 10471d7fec4Smrg * Copyright (c) 1999-2001 10571d7fec4Smrg * National Semiconductor Corporation. 10671d7fec4Smrg * All rights reserved. 10771d7fec4Smrg * 10871d7fec4Smrg * Redistribution and use in source and binary forms, with or without 10971d7fec4Smrg * modification, are permitted under the terms of the GNU General 11071d7fec4Smrg * Public License as published by the Free Software Foundation; either 11171d7fec4Smrg * version 2 of the License, or (at your option) any later version 11271d7fec4Smrg * 11371d7fec4Smrg * In addition to the terms of the GNU General Public License, neither 11471d7fec4Smrg * the name of the National Semiconductor Corporation nor the names of 11571d7fec4Smrg * its contributors may be used to endorse or promote products derived 11671d7fec4Smrg * from this software without specific prior written permission. 11771d7fec4Smrg * 11871d7fec4Smrg * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 11971d7fec4Smrg * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 12071d7fec4Smrg * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 12171d7fec4Smrg * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 12271d7fec4Smrg * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY 12371d7fec4Smrg * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 12471d7fec4Smrg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 12571d7fec4Smrg * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 12671d7fec4Smrg * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 12771d7fec4Smrg * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, 12871d7fec4Smrg * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY 12971d7fec4Smrg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 13071d7fec4Smrg * OF SUCH DAMAGE. See the GNU General Public License for more details. 13171d7fec4Smrg * 13271d7fec4Smrg * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF 13371d7fec4Smrg * YOUR JURISDICTION. It is licensee's responsibility to comply with 13471d7fec4Smrg * any export regulations applicable in licensee's jurisdiction. Under 13571d7fec4Smrg * CURRENT (2001) U.S. export regulations this software 13671d7fec4Smrg * is eligible for export from the U.S. and can be downloaded by or 13771d7fec4Smrg * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed 13871d7fec4Smrg * destinations which include Cuba, Iraq, Libya, North Korea, Iran, 13971d7fec4Smrg * Syria, Sudan, Afghanistan and any other country to which the U.S. 14071d7fec4Smrg * has embargoed goods and services. 14171d7fec4Smrg * 14271d7fec4Smrg * You should have received a copy of the GNU General Public License 14371d7fec4Smrg * along with this file; if not, write to the Free Software Foundation, 14471d7fec4Smrg * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 14571d7fec4Smrg * 14671d7fec4Smrg * END_NSC_LIC_GPL */ 14771d7fec4Smrg 14871d7fec4Smrgvoid gu1_set_bpp(unsigned short bpp); 14971d7fec4Smrgvoid gu1_set_solid_pattern(unsigned long color); 15071d7fec4Smrgvoid gu1_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor, 15171d7fec4Smrg unsigned long data0, unsigned long data1, 15271d7fec4Smrg unsigned char transparency); 15371d7fec4Smrgvoid gu1_set_color_pattern(unsigned long bgcolor, unsigned long fgcolor, 15471d7fec4Smrg unsigned long data0, unsigned long data1, 15571d7fec4Smrg unsigned long data2, unsigned long data3, 15671d7fec4Smrg unsigned char transparency); 15771d7fec4Smrgvoid gu1_load_color_pattern_line(short y, unsigned long *pattern_8x8); 15871d7fec4Smrgvoid gu1_set_solid_source(unsigned long color); 15971d7fec4Smrgvoid gu1_set_mono_source(unsigned long bgcolor, unsigned long fgcolor, 16071d7fec4Smrg unsigned short transparent); 16171d7fec4Smrgvoid gu1_set_pattern_flags(unsigned short flags); 16271d7fec4Smrgvoid gu1_set_raster_operation(unsigned char rop); 16371d7fec4Smrgvoid gu1_pattern_fill(unsigned short x, unsigned short y, 16471d7fec4Smrg unsigned short width, unsigned short height); 16571d7fec4Smrgvoid gu1_color_pattern_fill(unsigned short x, unsigned short y, 16671d7fec4Smrg unsigned short width, unsigned short height, 16771d7fec4Smrg unsigned long *pattern); 16871d7fec4Smrgvoid gu1_screen_to_screen_blt(unsigned short srcx, unsigned short srcy, 16971d7fec4Smrg unsigned short dstx, unsigned short dsty, 17071d7fec4Smrg unsigned short width, unsigned short height); 17171d7fec4Smrgvoid gu1_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy, 17271d7fec4Smrg unsigned short dstx, unsigned short dsty, 17371d7fec4Smrg unsigned short width, unsigned short height, 17471d7fec4Smrg unsigned long color); 17571d7fec4Smrgvoid gu1_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, 17671d7fec4Smrg unsigned short dstx, unsigned short dsty, 17771d7fec4Smrg unsigned short width, 17871d7fec4Smrg unsigned short height, 17971d7fec4Smrg unsigned char *data, long pitch); 18071d7fec4Smrgvoid gu1_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy, 18171d7fec4Smrg unsigned short dstx, unsigned short dsty, 18271d7fec4Smrg unsigned short width, 18371d7fec4Smrg unsigned short height, 18471d7fec4Smrg unsigned char *data, long pitch, 18571d7fec4Smrg unsigned long color); 18671d7fec4Smrgvoid gu1_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, 18771d7fec4Smrg unsigned short dstx, unsigned short dsty, 18871d7fec4Smrg unsigned short width, 18971d7fec4Smrg unsigned short height, unsigned char *data, 19071d7fec4Smrg short pitch); 19171d7fec4Smrgvoid gu1_text_blt(unsigned short dstx, unsigned short dsty, 19271d7fec4Smrg unsigned short width, unsigned short height, 19371d7fec4Smrg unsigned char *data); 19471d7fec4Smrgvoid gu1_bresenham_line(unsigned short x, unsigned short y, 19571d7fec4Smrg unsigned short length, unsigned short initerr, 19671d7fec4Smrg unsigned short axialerr, unsigned short diagerr, 19771d7fec4Smrg unsigned short flags); 19871d7fec4Smrgvoid gu1_wait_until_idle(void); 19971d7fec4Smrg 20071d7fec4Smrg#if GFX_NO_IO_IN_WAIT_MACROS 20171d7fec4Smrg#define GFX_WAIT_PENDING while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING) { ; } 20271d7fec4Smrg#define GFX_WAIT_BUSY while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_BUSY) { ; } 20371d7fec4Smrg#define GFX_WAIT_PIPELINE while (READ_REG16(GP_BLIT_STATUS) & BS_PIPELINE_BUSY) { ; } 20471d7fec4Smrg#else 20571d7fec4Smrg#define GFX_WAIT_PENDING while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING) { INB (0x80); } 20671d7fec4Smrg#define GFX_WAIT_BUSY while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_BUSY) { INB (0x80); } 20771d7fec4Smrg#define GFX_WAIT_PIPELINE while (READ_REG16(GP_BLIT_STATUS) & BS_PIPELINE_BUSY) { INB (0x80); } 20871d7fec4Smrg#endif 20971d7fec4Smrg 21071d7fec4Smrgvoid gu1_detect_blt_buffer_base(void); 21171d7fec4Smrgint gu1_test_blt_pending(void); 21271d7fec4Smrgvoid gu1_solid_fill(unsigned short x, unsigned short y, 21371d7fec4Smrg unsigned short width, unsigned short height, 21471d7fec4Smrg unsigned long color); 21571d7fec4Smrg 21671d7fec4Smrg/*--------------------------------------------------------------------------- 21771d7fec4Smrg * GFX_SET_BPP 21871d7fec4Smrg * 21971d7fec4Smrg * This routine sets the bits per pixel value in the graphics engine. 22071d7fec4Smrg * It is also stored in a static variable to use in the future calls to 22171d7fec4Smrg * the rendering routines. 22271d7fec4Smrg *--------------------------------------------------------------------------- 22371d7fec4Smrg */ 22471d7fec4Smrg#if GFX_2DACCEL_DYNAMIC 22571d7fec4Smrgvoid 22671d7fec4Smrggu1_set_bpp(unsigned short bpp) 22771d7fec4Smrg#else 22871d7fec4Smrgvoid 22971d7fec4Smrggfx_set_bpp(unsigned short bpp) 23071d7fec4Smrg#endif 23171d7fec4Smrg{ 23271d7fec4Smrg int control = 0; 23371d7fec4Smrg unsigned short pitch = gfx_get_display_pitch(); 23471d7fec4Smrg 23571d7fec4Smrg GFXbpp = bpp; 23671d7fec4Smrg 23771d7fec4Smrg /* DETECT BASE ADDRESSES FOR BLT BUFFERS */ 23871d7fec4Smrg /* Different for 2K or 3K of scratchpad. Also need to calculate */ 23971d7fec4Smrg /* the number of pixels that can fit in a BLT buffer - need to */ 24071d7fec4Smrg /* subtract 16 for alignment considerations. The 2K case, for */ 24171d7fec4Smrg /* example, is 816 bytes wide, allowing 800 pixels in 8 BPP, which */ 24271d7fec4Smrg /* means rendering operations won't be split for 800x600. */ 24371d7fec4Smrg 24471d7fec4Smrg gu1_detect_blt_buffer_base(); 24571d7fec4Smrg GFXbufferWidthPixels = GFXbb1Base - GFXbb0Base - 16; 24671d7fec4Smrg if (bpp > 8) { 24771d7fec4Smrg /* If 16bpp, divide GFXbufferWidthPixels by 2 */ 24871d7fec4Smrg GFXbufferWidthPixels >>= 1; 24971d7fec4Smrg } 25071d7fec4Smrg 25171d7fec4Smrg /* SET THE GRAPHICS CONTROLLER BPP AND PITCH */ 25271d7fec4Smrg if (bpp > 8) { 25371d7fec4Smrg /* Set the 16bpp bit if necessary */ 25471d7fec4Smrg control = BC_16BPP; 25571d7fec4Smrg } 25671d7fec4Smrg if ((gfx_cpu_version == GFX_CPU_PYRAMID) && (pitch > 2048)) { 25771d7fec4Smrg control |= BC_FB_WIDTH_4096; 25871d7fec4Smrg } else if (pitch > 1024) { 25971d7fec4Smrg control |= BC_FB_WIDTH_2048; 26071d7fec4Smrg } 26171d7fec4Smrg GFX_WAIT_BUSY; 26271d7fec4Smrg WRITE_REG32(GP_BLIT_STATUS, control); 26371d7fec4Smrg} 26471d7fec4Smrg 26571d7fec4Smrg/* 26671d7fec4Smrg//--------------------------------------------------------------------------- 26771d7fec4Smrg// GFX_SET_SOLID_SOURCE 26871d7fec4Smrg// 26971d7fec4Smrg// This routine is used to specify a solid source color. For the Xfree96 27071d7fec4Smrg// display driver, the source color is used to specify a planemask and the 27171d7fec4Smrg// ROP is adjusted accordingly. 27271d7fec4Smrg//--------------------------------------------------------------------------- 27371d7fec4Smrg*/ 27471d7fec4Smrg#if GFX_2DACCEL_DYNAMIC 27571d7fec4Smrgvoid 27671d7fec4Smrggu1_set_solid_source(unsigned long color) 27771d7fec4Smrg#else 27871d7fec4Smrgvoid 27971d7fec4Smrggfx_set_solid_source(unsigned long color) 28071d7fec4Smrg#endif 28171d7fec4Smrg{ 28271d7fec4Smrg /* CLEAR TRANSPARENCY FLAG */ 28371d7fec4Smrg 28471d7fec4Smrg GFXsourceFlags = 0; 28571d7fec4Smrg 28671d7fec4Smrg /* FORMAT 8 BPP COLOR */ 28771d7fec4Smrg /* GX requires 8BPP color data be duplicated into bits [15:8]. */ 28871d7fec4Smrg 28971d7fec4Smrg if (GFXbpp == 8) { 29071d7fec4Smrg color &= 0x00FF; 29171d7fec4Smrg color |= (color << 8); 29271d7fec4Smrg } 29371d7fec4Smrg 29471d7fec4Smrg /* POLL UNTIL ABLE TO WRITE THE SOURCE COLOR */ 29571d7fec4Smrg 29671d7fec4Smrg GFX_WAIT_PENDING; 29771d7fec4Smrg WRITE_REG16(GP_SRC_COLOR_0, (unsigned short)color); 29871d7fec4Smrg WRITE_REG16(GP_SRC_COLOR_1, (unsigned short)color); 29971d7fec4Smrg} 30071d7fec4Smrg 30171d7fec4Smrg/* 30271d7fec4Smrg//--------------------------------------------------------------------------- 30371d7fec4Smrg// GFX_SET_MONO_SOURCE 30471d7fec4Smrg// 30571d7fec4Smrg// This routine is used to specify the monochrome source colors. 30671d7fec4Smrg// It must be called *after* loading any pattern data (those routines 30771d7fec4Smrg// clear the source flags). 30871d7fec4Smrg//--------------------------------------------------------------------------- 30971d7fec4Smrg*/ 31071d7fec4Smrg#if GFX_2DACCEL_DYNAMIC 31171d7fec4Smrgvoid 31271d7fec4Smrggu1_set_mono_source(unsigned long bgcolor, unsigned long fgcolor, 31371d7fec4Smrg unsigned short transparent) 31471d7fec4Smrg#else 31571d7fec4Smrgvoid 31671d7fec4Smrggfx_set_mono_source(unsigned long bgcolor, unsigned long fgcolor, 31771d7fec4Smrg unsigned short transparent) 31871d7fec4Smrg#endif 31971d7fec4Smrg{ 32071d7fec4Smrg /* SET TRANSPARENCY FLAG */ 32171d7fec4Smrg 32271d7fec4Smrg GFXsourceFlags = transparent ? RM_SRC_TRANSPARENT : 0; 32371d7fec4Smrg 32471d7fec4Smrg /* FORMAT 8 BPP COLOR */ 32571d7fec4Smrg /* GX requires 8BPP color data be duplicated into bits [15:8]. */ 32671d7fec4Smrg 32771d7fec4Smrg if (GFXbpp == 8) { 32871d7fec4Smrg bgcolor &= 0x00FF; 32971d7fec4Smrg bgcolor |= (bgcolor << 8); 33071d7fec4Smrg fgcolor &= 0x00FF; 33171d7fec4Smrg fgcolor |= (fgcolor << 8); 33271d7fec4Smrg } 33371d7fec4Smrg 33471d7fec4Smrg /* POLL UNTIL ABLE TO WRITE THE SOURCE COLOR */ 33571d7fec4Smrg 33671d7fec4Smrg GFX_WAIT_PENDING; 33771d7fec4Smrg WRITE_REG16(GP_SRC_COLOR_0, (unsigned short)bgcolor); 33871d7fec4Smrg WRITE_REG16(GP_SRC_COLOR_1, (unsigned short)fgcolor); 33971d7fec4Smrg} 34071d7fec4Smrg 34171d7fec4Smrg/* 34271d7fec4Smrg//--------------------------------------------------------------------------- 34371d7fec4Smrg// GFX_SET_SOLID_PATTERN 34471d7fec4Smrg// 34571d7fec4Smrg// This routine is used to specify a solid pattern color. It is called 34671d7fec4Smrg// before performing solid rectangle fills or more complicated BLTs that 34771d7fec4Smrg// use a solid pattern color. 34871d7fec4Smrg// 34971d7fec4Smrg// The driver should always call "gfx_load_raster_operation" after a call 35071d7fec4Smrg// to this routine to make sure that the pattern flags are set appropriately. 35171d7fec4Smrg//--------------------------------------------------------------------------- 35271d7fec4Smrg*/ 35371d7fec4Smrg#if GFX_2DACCEL_DYNAMIC 35471d7fec4Smrgvoid 35571d7fec4Smrggu1_set_solid_pattern(unsigned long color) 35671d7fec4Smrg#else 35771d7fec4Smrgvoid 35871d7fec4Smrggfx_set_solid_pattern(unsigned long color) 35971d7fec4Smrg#endif 36071d7fec4Smrg{ 36171d7fec4Smrg /* CLEAR TRANSPARENCY FLAG */ 36271d7fec4Smrg 36371d7fec4Smrg GFXsourceFlags = 0; 36471d7fec4Smrg 36571d7fec4Smrg /* SET PATTERN FLAGS */ 36671d7fec4Smrg 36771d7fec4Smrg GFXpatternFlags = 0; 36871d7fec4Smrg 36971d7fec4Smrg /* FORMAT 8 BPP COLOR */ 37071d7fec4Smrg /* GX requires 8BPP color data be duplicated into bits [15:8]. */ 37171d7fec4Smrg 37271d7fec4Smrg if (GFXbpp == 8) { 37371d7fec4Smrg color &= 0x00FF; 37471d7fec4Smrg color |= (color << 8); 37571d7fec4Smrg } 37671d7fec4Smrg 37771d7fec4Smrg /* SAVE THE REFORMATTED COLOR FOR LATER */ 37871d7fec4Smrg /* Used to call the "GFX_solid_fill" routine for special cases. */ 37971d7fec4Smrg 38071d7fec4Smrg GFXsavedColor = color; 38171d7fec4Smrg 38271d7fec4Smrg /* POLL UNTIL ABLE TO WRITE THE PATTERN COLOR */ 38371d7fec4Smrg 38471d7fec4Smrg GFX_WAIT_PENDING; 38571d7fec4Smrg WRITE_REG16(GP_PAT_COLOR_0, (unsigned short)color); 38671d7fec4Smrg} 38771d7fec4Smrg 38871d7fec4Smrg/* 38971d7fec4Smrg//--------------------------------------------------------------------------- 39071d7fec4Smrg// GFX_SET_MONO_PATTERN 39171d7fec4Smrg// 39271d7fec4Smrg// This routine is used to specify a monochrome pattern. 39371d7fec4Smrg//--------------------------------------------------------------------------- 39471d7fec4Smrg*/ 39571d7fec4Smrg#if GFX_2DACCEL_DYNAMIC 39671d7fec4Smrgvoid 39771d7fec4Smrggu1_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor, 39871d7fec4Smrg unsigned long data0, unsigned long data1, 39971d7fec4Smrg unsigned char transparent) 40071d7fec4Smrg#else 40171d7fec4Smrgvoid 40271d7fec4Smrggfx_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor, 40371d7fec4Smrg unsigned long data0, unsigned long data1, 40471d7fec4Smrg unsigned char transparent) 40571d7fec4Smrg#endif 40671d7fec4Smrg{ 40771d7fec4Smrg /* CLEAR TRANSPARENCY FLAG */ 40871d7fec4Smrg 40971d7fec4Smrg GFXsourceFlags = 0; 41071d7fec4Smrg 41171d7fec4Smrg /* SET PATTERN FLAGS */ 41271d7fec4Smrg 41371d7fec4Smrg GFXpatternFlags = transparent ? RM_PAT_MONO | RM_PAT_TRANSPARENT : 41471d7fec4Smrg RM_PAT_MONO; 41571d7fec4Smrg 41671d7fec4Smrg /* FORMAT 8 BPP COLOR */ 41771d7fec4Smrg /* GXm requires 8BPP color data be duplicated into bits [15:8]. */ 41871d7fec4Smrg 41971d7fec4Smrg if (GFXbpp == 8) { 42071d7fec4Smrg bgcolor &= 0x00FF; 42171d7fec4Smrg bgcolor |= (bgcolor << 8); 42271d7fec4Smrg fgcolor &= 0x00FF; 42371d7fec4Smrg fgcolor |= (fgcolor << 8); 42471d7fec4Smrg } 42571d7fec4Smrg 42671d7fec4Smrg /* POLL UNTIL ABLE TO WRITE THE PATTERN COLORS AND DATA */ 42771d7fec4Smrg 42871d7fec4Smrg GFX_WAIT_PENDING; 42971d7fec4Smrg WRITE_REG16(GP_PAT_COLOR_0, (unsigned short)bgcolor); 43071d7fec4Smrg WRITE_REG16(GP_PAT_COLOR_1, (unsigned short)fgcolor); 43171d7fec4Smrg WRITE_REG32(GP_PAT_DATA_0, data0); 43271d7fec4Smrg WRITE_REG32(GP_PAT_DATA_1, data1); 43371d7fec4Smrg} 43471d7fec4Smrg 43571d7fec4Smrg/* 43671d7fec4Smrg//--------------------------------------------------------------------------- 43771d7fec4Smrg// GFX_SET_COLOR_PATTERN 43871d7fec4Smrg// 43971d7fec4Smrg// This routine is used to specify a color pattern. 44071d7fec4Smrg//--------------------------------------------------------------------------- 44171d7fec4Smrg*/ 44271d7fec4Smrg#if GFX_2DACCEL_DYNAMIC 44371d7fec4Smrgvoid 44471d7fec4Smrggu1_set_color_pattern(unsigned long bgcolor, unsigned long fgcolor, 44571d7fec4Smrg unsigned long data0, unsigned long data1, 44671d7fec4Smrg unsigned long data2, unsigned long data3, 44771d7fec4Smrg unsigned char transparent) 44871d7fec4Smrg#else 44971d7fec4Smrgvoid 45071d7fec4Smrggfx_set_color_pattern(unsigned long bgcolor, unsigned long fgcolor, 45171d7fec4Smrg unsigned long data0, unsigned long data1, 45271d7fec4Smrg unsigned long data2, unsigned long data3, 45371d7fec4Smrg unsigned char transparent) 45471d7fec4Smrg#endif 45571d7fec4Smrg{ 45671d7fec4Smrg /* CLEAR TRANSPARENCY FLAG */ 45771d7fec4Smrg 45871d7fec4Smrg GFXsourceFlags = 0; 45971d7fec4Smrg 46071d7fec4Smrg /* SET PATTERN FLAGS */ 46171d7fec4Smrg 46271d7fec4Smrg GFXpatternFlags = transparent ? RM_PAT_MONO | RM_PAT_TRANSPARENT : 46371d7fec4Smrg RM_PAT_MONO; 46471d7fec4Smrg 46571d7fec4Smrg GFXpatternFlags |= RM_PAT_COLOR; 46671d7fec4Smrg /* FORMAT 8 BPP COLOR */ 46771d7fec4Smrg /* GXm requires 8BPP color data be duplicated into bits [15:8]. */ 46871d7fec4Smrg 46971d7fec4Smrg if (GFXbpp == 8) { 47071d7fec4Smrg bgcolor &= 0x00FF; 47171d7fec4Smrg bgcolor |= (bgcolor << 8); 47271d7fec4Smrg fgcolor &= 0x00FF; 47371d7fec4Smrg fgcolor |= (fgcolor << 8); 47471d7fec4Smrg } 47571d7fec4Smrg 47671d7fec4Smrg /* POLL UNTIL ABLE TO WRITE THE PATTERN COLORS AND DATA */ 47771d7fec4Smrg 47871d7fec4Smrg GFX_WAIT_PENDING; 47971d7fec4Smrg WRITE_REG16(GP_PAT_COLOR_0, (unsigned short)bgcolor); 48071d7fec4Smrg WRITE_REG16(GP_PAT_COLOR_1, (unsigned short)fgcolor); 48171d7fec4Smrg WRITE_REG32(GP_PAT_DATA_0, data0); 48271d7fec4Smrg WRITE_REG32(GP_PAT_DATA_1, data1); 48371d7fec4Smrg if (GFXbpp > 8) { 48471d7fec4Smrg WRITE_REG32(GP_PAT_DATA_2, data2); 48571d7fec4Smrg WRITE_REG32(GP_PAT_DATA_3, data3); 48671d7fec4Smrg } 48771d7fec4Smrg} 48871d7fec4Smrg 48971d7fec4Smrg/* 49071d7fec4Smrg//--------------------------------------------------------------------------- 49171d7fec4Smrg// GFX_LOAD_COLOR_PATTERN_LINE 49271d7fec4Smrg// 49371d7fec4Smrg// This routine is used to load a single line of a 8x8 color pattern. 49471d7fec4Smrg//--------------------------------------------------------------------------- 49571d7fec4Smrg*/ 49671d7fec4Smrg#if GFX_2DACCEL_DYNAMIC 49771d7fec4Smrgvoid 49871d7fec4Smrggu1_load_color_pattern_line(short y, unsigned long *pattern_8x8) 49971d7fec4Smrg#else 50071d7fec4Smrgvoid 50171d7fec4Smrggfx_load_color_pattern_line(short y, unsigned long *pattern_8x8) 50271d7fec4Smrg#endif 50371d7fec4Smrg{ 50471d7fec4Smrg /* CLEAR TRANSPARENCY FLAG */ 50571d7fec4Smrg 50671d7fec4Smrg GFXsourceFlags = 0; 50771d7fec4Smrg 50871d7fec4Smrg /* SET PATTERN FLAGS */ 50971d7fec4Smrg 51071d7fec4Smrg GFXpatternFlags = RM_PAT_COLOR; 51171d7fec4Smrg 51271d7fec4Smrg y &= 7; 51371d7fec4Smrg 51471d7fec4Smrg if (GFXbpp > 8) 51571d7fec4Smrg pattern_8x8 += (y << 2); 51671d7fec4Smrg else 51771d7fec4Smrg pattern_8x8 += (y << 1); 51871d7fec4Smrg 51971d7fec4Smrg /* POLL UNTIL ABLE TO WRITE THE PATTERN COLORS AND DATA */ 52071d7fec4Smrg 52171d7fec4Smrg GFX_WAIT_PENDING; 52271d7fec4Smrg WRITE_REG32(GP_PAT_DATA_0, pattern_8x8[0]); 52371d7fec4Smrg WRITE_REG32(GP_PAT_DATA_1, pattern_8x8[1]); 52471d7fec4Smrg if (GFXbpp > 8) { 52571d7fec4Smrg WRITE_REG32(GP_PAT_DATA_2, pattern_8x8[2]); 52671d7fec4Smrg WRITE_REG32(GP_PAT_DATA_3, pattern_8x8[3]); 52771d7fec4Smrg } 52871d7fec4Smrg} 52971d7fec4Smrg 53071d7fec4Smrg/* 53171d7fec4Smrg//--------------------------------------------------------------------------- 53271d7fec4Smrg// GFX_SET_RASTER_OPERATION 53371d7fec4Smrg// 53471d7fec4Smrg// This routine loads the specified raster operation. It sets the pattern 53571d7fec4Smrg// flags appropriately. 53671d7fec4Smrg//--------------------------------------------------------------------------- 53771d7fec4Smrg*/ 53871d7fec4Smrg#if GFX_2DACCEL_DYNAMIC 53971d7fec4Smrgvoid 54071d7fec4Smrggu1_set_raster_operation(unsigned char rop) 54171d7fec4Smrg#else 54271d7fec4Smrgvoid 54371d7fec4Smrggfx_set_raster_operation(unsigned char rop) 54471d7fec4Smrg#endif 54571d7fec4Smrg{ 54671d7fec4Smrg unsigned short rop16; 54771d7fec4Smrg 54871d7fec4Smrg /* GENERATE 16-BIT VERSION OF ROP WITH PATTERN FLAGS */ 54971d7fec4Smrg 55071d7fec4Smrg rop16 = (unsigned short)rop | GFXpatternFlags; 55171d7fec4Smrg if ((rop & 0x33) ^ ((rop >> 2) & 0x33)) 55271d7fec4Smrg rop16 |= GFXsourceFlags; 55371d7fec4Smrg 55471d7fec4Smrg /* SAVE ROP FOR LATER COMPARISONS */ 55571d7fec4Smrg /* Need to have the pattern flags included */ 55671d7fec4Smrg 55771d7fec4Smrg GFXsavedRop = rop16; 55871d7fec4Smrg 55971d7fec4Smrg /* SET FLAG INDICATING ROP REQUIRES DESTINATION DATA */ 56071d7fec4Smrg /* True if even bits (0:2:4:6) do not equal the correspinding */ 56171d7fec4Smrg /* even bits (1:3:5:7). */ 56271d7fec4Smrg 56371d7fec4Smrg GFXusesDstData = ((rop & 0x55) ^ ((rop >> 1) & 0x55)); 56471d7fec4Smrg 56571d7fec4Smrg /* POLL UNTIL ABLE TO WRITE THE PATTERN COLOR */ 56671d7fec4Smrg /* Only one operation can be pending at a time. */ 56771d7fec4Smrg 56871d7fec4Smrg GFX_WAIT_PENDING; 56971d7fec4Smrg WRITE_REG16(GP_RASTER_MODE, rop16); 57071d7fec4Smrg} 57171d7fec4Smrg 57271d7fec4Smrg/* 57371d7fec4Smrg//--------------------------------------------------------------------------- 57471d7fec4Smrg// GFX_SOLID_FILL 57571d7fec4Smrg// 57671d7fec4Smrg// This routine MUST be used when performing a solid rectangle fill with 57771d7fec4Smrg// the ROPs of PATCOPY (0xF0), BLACKNESS (0x00), WHITENESS (0xFF), or 57871d7fec4Smrg// PATINVERT (0x0F). There is a bug in GXm for these cases that requires a 57971d7fec4Smrg// workaround. 58071d7fec4Smrg// 58171d7fec4Smrg// For BLACKNESS (ROP = 0x00), set the color to 0x0000. 58271d7fec4Smrg// For WHITENESS (ROP = 0xFF), set the color to 0xFFFF. 58371d7fec4Smrg// For PATINVERT (ROP = 0x0F), invert the desired color. 58471d7fec4Smrg// 58571d7fec4Smrg// X screen X position (left) 58671d7fec4Smrg// Y screen Y position (top) 58771d7fec4Smrg// WIDTH width of rectangle, in pixels 58871d7fec4Smrg// HEIGHT height of rectangle, in scanlines 58971d7fec4Smrg// COLOR fill color 59071d7fec4Smrg// 59171d7fec4Smrg// THIS ROUTINE SHOULD NOT BE DIRECTLY CALLED FROM THE DRIVER. The driver 59271d7fec4Smrg// should always use GFX_pattern_fill and let that routine call this one 59371d7fec4Smrg// when approipriate. This is to hide quirks specific to MediaGX hardware. 59471d7fec4Smrg//--------------------------------------------------------------------------- 59571d7fec4Smrg*/ 59671d7fec4Smrgvoid 59771d7fec4Smrggu1_solid_fill(unsigned short x, unsigned short y, 59871d7fec4Smrg unsigned short width, unsigned short height, 59971d7fec4Smrg unsigned long color) 60071d7fec4Smrg{ 60171d7fec4Smrg unsigned short section; 60271d7fec4Smrg 60371d7fec4Smrg /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 60471d7fec4Smrg /* Only one operation can be pending at a time. */ 60571d7fec4Smrg 60671d7fec4Smrg GFX_WAIT_PENDING; 60771d7fec4Smrg 60871d7fec4Smrg /* SET REGISTERS TO DRAW RECTANGLE */ 60971d7fec4Smrg 61071d7fec4Smrg WRITE_REG16(GP_DST_XCOOR, x); 61171d7fec4Smrg WRITE_REG16(GP_DST_YCOOR, y); 61271d7fec4Smrg WRITE_REG16(GP_HEIGHT, height); 61371d7fec4Smrg WRITE_REG16(GP_RASTER_MODE, 0x00F0); /* PATCOPY */ 61471d7fec4Smrg WRITE_REG16(GP_PAT_COLOR_0, (unsigned short)color); 61571d7fec4Smrg 61671d7fec4Smrg /* CHECK WIDTH FOR GX BUG WORKAROUND */ 61771d7fec4Smrg 61871d7fec4Smrg if (width <= 16) { 61971d7fec4Smrg /* OK TO DRAW SMALL RECTANGLE IN ONE PASS */ 62071d7fec4Smrg 62171d7fec4Smrg WRITE_REG16(GP_WIDTH, width); 62271d7fec4Smrg WRITE_REG16(GP_BLIT_MODE, 0); 62371d7fec4Smrg } else { 62471d7fec4Smrg /* DRAW FIRST PART OF RECTANGLE */ 62571d7fec4Smrg /* Get to a 16 pixel boundary. */ 62671d7fec4Smrg 62771d7fec4Smrg section = 0x10 - (x & 0x0F); 62871d7fec4Smrg WRITE_REG16(GP_WIDTH, section); 62971d7fec4Smrg WRITE_REG16(GP_BLIT_MODE, 0); 63071d7fec4Smrg 63171d7fec4Smrg /* POLL UNTIL ABLE TO LOAD THE SECOND RECTANGLE */ 63271d7fec4Smrg 63371d7fec4Smrg GFX_WAIT_PENDING; 63471d7fec4Smrg WRITE_REG16(GP_DST_XCOOR, x + section); 63571d7fec4Smrg WRITE_REG16(GP_DST_YCOOR, y); 63671d7fec4Smrg WRITE_REG16(GP_WIDTH, width - section); 63771d7fec4Smrg WRITE_REG16(GP_BLIT_MODE, 0); 63871d7fec4Smrg } 63971d7fec4Smrg} 64071d7fec4Smrg 64171d7fec4Smrg/* 64271d7fec4Smrg//---------------------------------------------------------------------------- 64371d7fec4Smrg// GFX_PATTERN_FILL 64471d7fec4Smrg// 64571d7fec4Smrg// This routine is used to fill a rectangular region. The pattern must 64671d7fec4Smrg// be previously loaded using one of GFX_load_*_pattern routines. Also, the 64771d7fec4Smrg// raster operation must be previously specified using the 64871d7fec4Smrg// "GFX_load_raster_operation" routine. 64971d7fec4Smrg// 65071d7fec4Smrg// X screen X position (left) 65171d7fec4Smrg// Y screen Y position (top) 65271d7fec4Smrg// WIDTH width of rectangle, in pixels 65371d7fec4Smrg// HEIGHT height of rectangle, in scanlines 65471d7fec4Smrg//---------------------------------------------------------------------------- 65571d7fec4Smrg*/ 65671d7fec4Smrg#if GFX_2DACCEL_DYNAMIC 65771d7fec4Smrgvoid 65871d7fec4Smrggu1_pattern_fill(unsigned short x, unsigned short y, 65971d7fec4Smrg unsigned short width, unsigned short height) 66071d7fec4Smrg#else 66171d7fec4Smrgvoid 66271d7fec4Smrggfx_pattern_fill(unsigned short x, unsigned short y, 66371d7fec4Smrg unsigned short width, unsigned short height) 66471d7fec4Smrg#endif 66571d7fec4Smrg{ 66671d7fec4Smrg unsigned short section, buffer_width, blit_mode; 66771d7fec4Smrg 66871d7fec4Smrg /* CHECK IF OPTIMIZED SOLID CASES */ 66971d7fec4Smrg /* Check all 16 bits of the ROP to include solid pattern flags. */ 67071d7fec4Smrg 67171d7fec4Smrg switch (GFXsavedRop) { 67271d7fec4Smrg /* CHECK FOR SPECIAL CASES WITHOUT DESTINATION DATA */ 67371d7fec4Smrg /* Need hardware workaround for fast "burst write" cases. */ 67471d7fec4Smrg 67571d7fec4Smrg case 0x00F0: 67671d7fec4Smrg gu1_solid_fill(x, y, width, height, (unsigned short)GFXsavedColor); 67771d7fec4Smrg break; 67871d7fec4Smrg case 0x000F: 67971d7fec4Smrg gu1_solid_fill(x, y, width, height, (unsigned short)~GFXsavedColor); 68071d7fec4Smrg break; 68171d7fec4Smrg case 0x0000: 68271d7fec4Smrg gu1_solid_fill(x, y, width, height, 0x0000); 68371d7fec4Smrg break; 68471d7fec4Smrg case 0x00FF: 68571d7fec4Smrg gu1_solid_fill(x, y, width, height, 0xFFFF); 68671d7fec4Smrg break; 68771d7fec4Smrg 68871d7fec4Smrg /* REMAINING CASES REQUIRE DESTINATION DATA OR NOT SOLID COLOR */ 68971d7fec4Smrg 69071d7fec4Smrg default: 69171d7fec4Smrg 69271d7fec4Smrg /* DETERMINE BLT MODE VALUE */ 69371d7fec4Smrg /* Still here for non-solid patterns without destination data. */ 69471d7fec4Smrg 69571d7fec4Smrg blit_mode = GFXusesDstData ? BM_READ_DST_FB0 : 0; 69671d7fec4Smrg 69771d7fec4Smrg /* SET SOURCE EXPANSION MODE */ 69871d7fec4Smrg /* If the ROP requires source data, then the source data is all 1's */ 69971d7fec4Smrg /* and then expanded into the desired color in GP_SRC_COLOR_1. */ 70071d7fec4Smrg 70171d7fec4Smrg blit_mode |= BM_SOURCE_EXPAND; 70271d7fec4Smrg 70371d7fec4Smrg /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 70471d7fec4Smrg /* Write the registers that do not change for each section. */ 70571d7fec4Smrg 70671d7fec4Smrg GFX_WAIT_PENDING; 70771d7fec4Smrg WRITE_REG16(GP_HEIGHT, height); 70871d7fec4Smrg 70971d7fec4Smrg /* SINCE ONLY DESTINATION DATA, WE CAN USE BOTH BB0 AND BB1. */ 71071d7fec4Smrg /* Therefore, width available = BLT buffer width * 2. */ 71171d7fec4Smrg 71271d7fec4Smrg buffer_width = GFXbufferWidthPixels << 1; 71371d7fec4Smrg 71471d7fec4Smrg /* REPEAT UNTIL FINISHED WITH RECTANGLE */ 71571d7fec4Smrg /* Perform BLT in vertical sections, as wide as the BLT buffer */ 71671d7fec4Smrg /* allows. Hardware does not split the operations, so */ 71771d7fec4Smrg /* software must do it to avoid large scanlines that would */ 71871d7fec4Smrg /* overflow the BLT buffers. */ 71971d7fec4Smrg 72071d7fec4Smrg while (width > 0) { 72171d7fec4Smrg /* DETERMINE WIDTH OF SECTION */ 72271d7fec4Smrg 72371d7fec4Smrg if (width > buffer_width) 72471d7fec4Smrg section = buffer_width; 72571d7fec4Smrg else 72671d7fec4Smrg section = width; 72771d7fec4Smrg 72871d7fec4Smrg /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 72971d7fec4Smrg 73071d7fec4Smrg GFX_WAIT_PENDING; 73171d7fec4Smrg WRITE_REG16(GP_DST_XCOOR, x); 73271d7fec4Smrg WRITE_REG16(GP_DST_YCOOR, y); 73371d7fec4Smrg WRITE_REG16(GP_WIDTH, section); 73471d7fec4Smrg WRITE_REG16(GP_BLIT_MODE, blit_mode); 73571d7fec4Smrg 73671d7fec4Smrg /* ADJUST PARAMETERS FOR NEXT SECTION */ 73771d7fec4Smrg 73871d7fec4Smrg width -= section; 73971d7fec4Smrg x += section; 74071d7fec4Smrg } 74171d7fec4Smrg break; 74271d7fec4Smrg } 74371d7fec4Smrg} 74471d7fec4Smrg 74571d7fec4Smrg/* 74671d7fec4Smrg//---------------------------------------------------------------------------- 74771d7fec4Smrg// GFX_COLOR_PATTERN_FILL 74871d7fec4Smrg// 74971d7fec4Smrg// This routine is used to render a rectangle using the current raster 75071d7fec4Smrg// operation and the specified color pattern. It allows an 8x8 color 75171d7fec4Smrg// pattern to be rendered without multiple calls to the gfx_set_color_pattern 75271d7fec4Smrg// and gfx_pattern_fill routines. 75371d7fec4Smrg// 75471d7fec4Smrg// X screen X position (left) 75571d7fec4Smrg// Y screen Y position (top) 75671d7fec4Smrg// WIDTH width of rectangle, in pixels 75771d7fec4Smrg// HEIGHT height of rectangle, in scanlines 75871d7fec4Smrg// *PATTERN pointer to 8x8 color pattern data 75971d7fec4Smrg//---------------------------------------------------------------------------- 76071d7fec4Smrg*/ 76171d7fec4Smrg#if GFX_2DACCEL_DYNAMIC 76271d7fec4Smrgvoid 76371d7fec4Smrggu1_color_pattern_fill(unsigned short x, unsigned short y, 76471d7fec4Smrg unsigned short width, unsigned short height, 76571d7fec4Smrg unsigned long *pattern) 76671d7fec4Smrg#else 76771d7fec4Smrgvoid 76871d7fec4Smrggfx_color_pattern_fill(unsigned short x, unsigned short y, 76971d7fec4Smrg unsigned short width, unsigned short height, 77071d7fec4Smrg unsigned long *pattern) 77171d7fec4Smrg#endif 77271d7fec4Smrg{ 77371d7fec4Smrg unsigned short blit_mode, passes, cur_y, pat_y, i; 77471d7fec4Smrg unsigned short buffer_width, line_width; 77571d7fec4Smrg unsigned short bpp_shift, section, cur_x; 77671d7fec4Smrg 77771d7fec4Smrg /* SET APPROPRIATE INCREMENT */ 77871d7fec4Smrg 77971d7fec4Smrg bpp_shift = (GFXbpp > 8) ? 2 : 1; 78071d7fec4Smrg 78171d7fec4Smrg /* SET DESTINATION REQUIRED */ 78271d7fec4Smrg 78371d7fec4Smrg blit_mode = GFXusesDstData ? BM_READ_DST_FB0 : 0; 78471d7fec4Smrg 78571d7fec4Smrg /* SET SOURCE EXPANSION */ 78671d7fec4Smrg 78771d7fec4Smrg blit_mode |= BM_SOURCE_EXPAND; 78871d7fec4Smrg 78971d7fec4Smrg /* OVERRIDE RASTER MODE TO FORCE A COLOR PATTERN */ 79071d7fec4Smrg 79171d7fec4Smrg GFX_WAIT_PENDING; 79271d7fec4Smrg WRITE_REG16(GP_RASTER_MODE, 79371d7fec4Smrg (GFXsavedRop & ~RM_PAT_MASK & ~RM_PAT_TRANSPARENT) | 79471d7fec4Smrg RM_PAT_COLOR); 79571d7fec4Smrg 79671d7fec4Smrg /* WRITE THE REGISTERS THAT DO NOT CHANGE */ 79771d7fec4Smrg /* If destination data is required, the width and */ 79871d7fec4Smrg /* x position will be overwritten. */ 79971d7fec4Smrg 80071d7fec4Smrg WRITE_REG16(GP_HEIGHT, 1); 80171d7fec4Smrg WRITE_REG16(GP_WIDTH, width); 80271d7fec4Smrg WRITE_REG16(GP_DST_XCOOR, x); 80371d7fec4Smrg 80471d7fec4Smrg /* THE ENTIRE PATTERN WILL NOT BE DRAWN IF THE HEIGHT IS LESS THAN 8 */ 80571d7fec4Smrg 80671d7fec4Smrg passes = (height < 8) ? height : 8; 80771d7fec4Smrg 80871d7fec4Smrg /* SINCE ONLY DESTINATION DATA, WE CAN USE BOTH BB0 AND BB1. */ 80971d7fec4Smrg /* Therefore, width available = BLT buffer width * 2. */ 81071d7fec4Smrg 81171d7fec4Smrg buffer_width = GFXbufferWidthPixels << 1; 81271d7fec4Smrg 81371d7fec4Smrg for (i = 0; i < passes; i++) { 81471d7fec4Smrg pat_y = ((y + i) & 7) << bpp_shift; 81571d7fec4Smrg cur_y = y + i; 81671d7fec4Smrg 81771d7fec4Smrg /* WRITE THE PATTERN DATA FOR THE ACTIVE LINE */ 81871d7fec4Smrg 81971d7fec4Smrg GFX_WAIT_PENDING; 82071d7fec4Smrg WRITE_REG32(GP_PAT_DATA_0, pattern[pat_y]); 82171d7fec4Smrg WRITE_REG32(GP_PAT_DATA_1, pattern[pat_y + 1]); 82271d7fec4Smrg 82371d7fec4Smrg if (GFXbpp > 8) { 82471d7fec4Smrg WRITE_REG32(GP_PAT_DATA_2, pattern[pat_y + 2]); 82571d7fec4Smrg WRITE_REG32(GP_PAT_DATA_3, pattern[pat_y + 3]); 82671d7fec4Smrg } 82771d7fec4Smrg 82871d7fec4Smrg /* SPLIT BLT LINE INTO SECTIONS IF REQUIRED */ 82971d7fec4Smrg /* If no destination data is required, we can ignore */ 83071d7fec4Smrg /* the BLT buffers. Otherwise, we must separate the BLT */ 83171d7fec4Smrg /* so as not to overflow the buffers */ 83271d7fec4Smrg 83371d7fec4Smrg if (blit_mode & BM_READ_DST_BB0) { 83471d7fec4Smrg line_width = width; 83571d7fec4Smrg cur_x = x; 83671d7fec4Smrg 83771d7fec4Smrg while (line_width) { 83871d7fec4Smrg section = (line_width > buffer_width) ? buffer_width : line_width; 83971d7fec4Smrg cur_y = y + i; 84071d7fec4Smrg 84171d7fec4Smrg GFX_WAIT_PENDING; 84271d7fec4Smrg WRITE_REG16(GP_DST_XCOOR, cur_x); 84371d7fec4Smrg WRITE_REG16(GP_WIDTH, section); 84471d7fec4Smrg 84571d7fec4Smrg while (cur_y < y + height) { 84671d7fec4Smrg GFX_WAIT_PENDING; 84771d7fec4Smrg WRITE_REG16(GP_DST_YCOOR, cur_y); 84871d7fec4Smrg WRITE_REG16(GP_BLIT_MODE, blit_mode); 84971d7fec4Smrg cur_y += 8; 85071d7fec4Smrg } 85171d7fec4Smrg 85271d7fec4Smrg cur_x += section; 85371d7fec4Smrg line_width -= section; 85471d7fec4Smrg } 85571d7fec4Smrg 85671d7fec4Smrg } else { 85771d7fec4Smrg while (cur_y < y + height) { 85871d7fec4Smrg GFX_WAIT_PENDING; 85971d7fec4Smrg WRITE_REG16(GP_DST_YCOOR, cur_y); 86071d7fec4Smrg WRITE_REG16(GP_BLIT_MODE, blit_mode); 86171d7fec4Smrg cur_y += 8; 86271d7fec4Smrg } 86371d7fec4Smrg } 86471d7fec4Smrg 86571d7fec4Smrg } 86671d7fec4Smrg 86771d7fec4Smrg /* RESTORE ORIGINAL ROP AND FLAGS */ 86871d7fec4Smrg 86971d7fec4Smrg GFX_WAIT_PENDING; 87071d7fec4Smrg WRITE_REG16(GP_RASTER_MODE, GFXsavedRop); 87171d7fec4Smrg 87271d7fec4Smrg} 87371d7fec4Smrg 87471d7fec4Smrg/* 87571d7fec4Smrg//---------------------------------------------------------------------------- 87671d7fec4Smrg// SCREEN TO SCREEN BLT 87771d7fec4Smrg// 87871d7fec4Smrg// This routine should be used to perform a screen to screen BLT when the 87971d7fec4Smrg// ROP does not require destination data. 88071d7fec4Smrg// 88171d7fec4Smrg// SRCX screen X position to copy from 88271d7fec4Smrg// SRCY screen Y position to copy from 88371d7fec4Smrg// DSTX screen X position to copy to 88471d7fec4Smrg// DSTY screen Y position to copy to 88571d7fec4Smrg// WIDTH width of rectangle, in pixels 88671d7fec4Smrg// HEIGHT height of rectangle, in scanlines 88771d7fec4Smrg//---------------------------------------------------------------------------- 88871d7fec4Smrg*/ 88971d7fec4Smrg#if GFX_2DACCEL_DYNAMIC 89071d7fec4Smrgvoid 89171d7fec4Smrggu1_screen_to_screen_blt(unsigned short srcx, unsigned short srcy, 89271d7fec4Smrg unsigned short dstx, unsigned short dsty, 89371d7fec4Smrg unsigned short width, unsigned short height) 89471d7fec4Smrg#else 89571d7fec4Smrgvoid 89671d7fec4Smrggfx_screen_to_screen_blt(unsigned short srcx, unsigned short srcy, 89771d7fec4Smrg unsigned short dstx, unsigned short dsty, 89871d7fec4Smrg unsigned short width, unsigned short height) 89971d7fec4Smrg#endif 90071d7fec4Smrg{ 90171d7fec4Smrg unsigned short section, buffer_width; 90271d7fec4Smrg unsigned short blit_mode; 90371d7fec4Smrg 90471d7fec4Smrg /* CHECK IF RASTER OPERATION REQUIRES DESTINATION DATA */ 90571d7fec4Smrg 90671d7fec4Smrg blit_mode = GFXusesDstData ? BM_READ_DST_FB1 | BM_READ_SRC_FB : 90771d7fec4Smrg BM_READ_SRC_FB; 90871d7fec4Smrg 90971d7fec4Smrg /* CHECK Y DIRECTION */ 91071d7fec4Smrg /* Hardware has support for negative Y direction. */ 91171d7fec4Smrg 91271d7fec4Smrg if (dsty > srcy) { 91371d7fec4Smrg blit_mode |= BM_REVERSE_Y; 91471d7fec4Smrg srcy += height - 1; 91571d7fec4Smrg dsty += height - 1; 91671d7fec4Smrg } 91771d7fec4Smrg 91871d7fec4Smrg /* CHECK X DIRECTION */ 91971d7fec4Smrg /* Hardware does not support negative X direction since at the time */ 92071d7fec4Smrg /* of development all supported resolutions could fit a scanline of */ 92171d7fec4Smrg /* data at once into the BLT buffers (using both BB0 and BB1). This */ 92271d7fec4Smrg /* code is more generic to allow for any size BLT buffer. */ 92371d7fec4Smrg 92471d7fec4Smrg if (dstx > srcx) { 92571d7fec4Smrg srcx += width; 92671d7fec4Smrg dstx += width; 92771d7fec4Smrg } 92871d7fec4Smrg 92971d7fec4Smrg /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 93071d7fec4Smrg /* Write the registers that do not change for each section. */ 93171d7fec4Smrg 93271d7fec4Smrg GFX_WAIT_PENDING; 93371d7fec4Smrg WRITE_REG16(GP_HEIGHT, height); 93471d7fec4Smrg 93571d7fec4Smrg /* CHECK AVAILABLE BLT BUFFER SIZE */ 93671d7fec4Smrg /* Can use both BLT buffers if no destination data is required. */ 93771d7fec4Smrg 93871d7fec4Smrg buffer_width = GFXusesDstData ? GFXbufferWidthPixels : 93971d7fec4Smrg GFXbufferWidthPixels << 1; 94071d7fec4Smrg 94171d7fec4Smrg /* REPEAT UNTIL FINISHED WITH RECTANGLE */ 94271d7fec4Smrg /* Perform BLT in vertical sections, as wide as the BLT buffer allows. */ 94371d7fec4Smrg /* Hardware does not split the operations, so software must do it to */ 94471d7fec4Smrg /* avoid large scanlines that would overflow the BLT buffers. */ 94571d7fec4Smrg 94671d7fec4Smrg while (width > 0) { 94771d7fec4Smrg /* CHECK WIDTH OF CURRENT SECTION */ 94871d7fec4Smrg 94971d7fec4Smrg if (width > buffer_width) 95071d7fec4Smrg section = buffer_width; 95171d7fec4Smrg else 95271d7fec4Smrg section = width; 95371d7fec4Smrg 95471d7fec4Smrg /* PROGRAM REGISTERS THAT ARE THE SAME FOR EITHER X DIRECTION */ 95571d7fec4Smrg 95671d7fec4Smrg GFX_WAIT_PENDING; 95771d7fec4Smrg WRITE_REG16(GP_SRC_YCOOR, srcy); 95871d7fec4Smrg WRITE_REG16(GP_DST_YCOOR, dsty); 95971d7fec4Smrg WRITE_REG16(GP_WIDTH, section); 96071d7fec4Smrg 96171d7fec4Smrg /* CHECK X DIRECTION */ 96271d7fec4Smrg 96371d7fec4Smrg if (dstx > srcx) { 96471d7fec4Smrg /* NEGATIVE X DIRECTION */ 96571d7fec4Smrg /* Still positive X direction within the section. */ 96671d7fec4Smrg 96771d7fec4Smrg srcx -= section; 96871d7fec4Smrg dstx -= section; 96971d7fec4Smrg WRITE_REG16(GP_SRC_XCOOR, srcx); 97071d7fec4Smrg WRITE_REG16(GP_DST_XCOOR, dstx); 97171d7fec4Smrg WRITE_REG16(GP_BLIT_MODE, blit_mode); 97271d7fec4Smrg } else { 97371d7fec4Smrg /* POSITIVE X DIRECTION */ 97471d7fec4Smrg 97571d7fec4Smrg WRITE_REG16(GP_SRC_XCOOR, srcx); 97671d7fec4Smrg WRITE_REG16(GP_DST_XCOOR, dstx); 97771d7fec4Smrg WRITE_REG16(GP_BLIT_MODE, blit_mode); 97871d7fec4Smrg dstx += section; 97971d7fec4Smrg srcx += section; 98071d7fec4Smrg } 98171d7fec4Smrg width -= section; 98271d7fec4Smrg } 98371d7fec4Smrg} 98471d7fec4Smrg 98571d7fec4Smrg/* 98671d7fec4Smrg//---------------------------------------------------------------------------- 98771d7fec4Smrg// SCREEN TO SCREEN TRANSPARENT BLT 98871d7fec4Smrg// 98971d7fec4Smrg// This routine should be used to perform a screen to screen BLT when a 99071d7fec4Smrg// specified color should by transparent. The only supported ROP is SRCCOPY. 99171d7fec4Smrg// 99271d7fec4Smrg// SRCX screen X position to copy from 99371d7fec4Smrg// SRCY screen Y position to copy from 99471d7fec4Smrg// DSTX screen X position to copy to 99571d7fec4Smrg// DSTY screen Y position to copy to 99671d7fec4Smrg// WIDTH width of rectangle, in pixels 99771d7fec4Smrg// HEIGHT height of rectangle, in scanlines 99871d7fec4Smrg// COLOR transparent color 99971d7fec4Smrg//---------------------------------------------------------------------------- 100071d7fec4Smrg*/ 100171d7fec4Smrg#if GFX_2DACCEL_DYNAMIC 100271d7fec4Smrgvoid 100371d7fec4Smrggu1_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy, 100471d7fec4Smrg unsigned short dstx, unsigned short dsty, 100571d7fec4Smrg unsigned short width, unsigned short height, 100671d7fec4Smrg unsigned long color) 100771d7fec4Smrg#else 100871d7fec4Smrgvoid 100971d7fec4Smrggfx_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy, 101071d7fec4Smrg unsigned short dstx, unsigned short dsty, 101171d7fec4Smrg unsigned short width, unsigned short height, 101271d7fec4Smrg unsigned long color) 101371d7fec4Smrg#endif 101471d7fec4Smrg{ 101571d7fec4Smrg unsigned short section, buffer_width; 101671d7fec4Smrg unsigned short blit_mode = BM_READ_SRC_FB; 101771d7fec4Smrg 101871d7fec4Smrg /* CHECK Y DIRECTION */ 101971d7fec4Smrg /* Hardware has support for negative Y direction. */ 102071d7fec4Smrg 102171d7fec4Smrg if (dsty > srcy) { 102271d7fec4Smrg blit_mode |= BM_REVERSE_Y; 102371d7fec4Smrg srcy += height - 1; 102471d7fec4Smrg dsty += height - 1; 102571d7fec4Smrg } 102671d7fec4Smrg 102771d7fec4Smrg /* CHECK X DIRECTION */ 102871d7fec4Smrg /* Hardware does not support negative X direction since at the time */ 102971d7fec4Smrg /* of development all supported resolutions could fit a scanline of */ 103071d7fec4Smrg /* data at once into the BLT buffers (using both BB0 and BB1). This */ 103171d7fec4Smrg /* code is more generic to allow for any size BLT buffer. */ 103271d7fec4Smrg 103371d7fec4Smrg if (dstx > srcx) { 103471d7fec4Smrg srcx += width; 103571d7fec4Smrg dstx += width; 103671d7fec4Smrg } 103771d7fec4Smrg 103871d7fec4Smrg /* CALCULATE BLT BUFFER SIZE */ 103971d7fec4Smrg /* Need to use BB1 to store the BLT buffer data. */ 104071d7fec4Smrg 104171d7fec4Smrg buffer_width = GFXbufferWidthPixels; 104271d7fec4Smrg 104371d7fec4Smrg /* WRITE TRANSPARENCY COLOR TO BLT BUFFER 1 */ 104471d7fec4Smrg 104571d7fec4Smrg if (GFXbpp == 8) { 104671d7fec4Smrg color &= 0x00FF; 104771d7fec4Smrg color |= (color << 8); 104871d7fec4Smrg } 104971d7fec4Smrg color = (color & 0x0000FFFF) | (color << 16); 105071d7fec4Smrg 105171d7fec4Smrg /* WAIT UNTIL PIPELINE IS NOT BUSY BEFORE LOADING DATA INTO BB1 */ 105271d7fec4Smrg /* Need to make sure any previous BLT using BB1 is complete. */ 105371d7fec4Smrg /* Only need to load 32 bits of BB1 for the 1 pixel BLT that follows. */ 105471d7fec4Smrg 105571d7fec4Smrg GFX_WAIT_BUSY; 105671d7fec4Smrg WRITE_SCRATCH32(GFXbb1Base, color); 105771d7fec4Smrg 105871d7fec4Smrg /* DO BOGUS BLT TO LATCH DATA FROM BB1 */ 105971d7fec4Smrg /* Already know graphics pipeline is idle. */ 106071d7fec4Smrg /* Only need to latch data into the holding registers for the current */ 106171d7fec4Smrg /* data from BB1. A 1 pixel wide BLT will suffice. */ 106271d7fec4Smrg 106371d7fec4Smrg WRITE_REG32(GP_DST_XCOOR, 0); 106471d7fec4Smrg WRITE_REG32(GP_SRC_XCOOR, 0); 106571d7fec4Smrg WRITE_REG32(GP_WIDTH, 0x00010001); 106671d7fec4Smrg WRITE_REG16(GP_RASTER_MODE, 0x00CC); 106771d7fec4Smrg WRITE_REG16(GP_BLIT_MODE, BM_READ_SRC_FB | BM_READ_DST_BB1); 106871d7fec4Smrg 106971d7fec4Smrg /* WRITE REGISTERS FOR REAL SCREEN TO SCREEN BLT */ 107071d7fec4Smrg 107171d7fec4Smrg GFX_WAIT_PENDING; 107271d7fec4Smrg WRITE_REG16(GP_HEIGHT, height); 107371d7fec4Smrg WRITE_REG16(GP_RASTER_MODE, 0x10C6); 107471d7fec4Smrg WRITE_REG32(GP_PAT_COLOR_0, 0xFFFFFFFF); 107571d7fec4Smrg 107671d7fec4Smrg /* REPEAT UNTIL FINISHED WITH RECTANGLE */ 107771d7fec4Smrg /* Perform BLT in vertical sections, as wide as the BLT buffer allows. */ 107871d7fec4Smrg /* Hardware does not split the operations, so software must do it to */ 107971d7fec4Smrg /* avoid large scanlines that would overflow the BLT buffers. */ 108071d7fec4Smrg 108171d7fec4Smrg while (width > 0) { 108271d7fec4Smrg /* CHECK WIDTH OF CURRENT SECTION */ 108371d7fec4Smrg 108471d7fec4Smrg if (width > buffer_width) 108571d7fec4Smrg section = buffer_width; 108671d7fec4Smrg else 108771d7fec4Smrg section = width; 108871d7fec4Smrg 108971d7fec4Smrg /* PROGRAM REGISTERS THAT ARE THE SAME FOR EITHER X DIRECTION */ 109071d7fec4Smrg 109171d7fec4Smrg GFX_WAIT_PENDING; 109271d7fec4Smrg WRITE_REG16(GP_SRC_YCOOR, srcy); 109371d7fec4Smrg WRITE_REG16(GP_DST_YCOOR, dsty); 109471d7fec4Smrg WRITE_REG16(GP_WIDTH, section); 109571d7fec4Smrg 109671d7fec4Smrg /* CHECK X DIRECTION */ 109771d7fec4Smrg /* Again, this must be done in software, and can be removed if the */ 109871d7fec4Smrg /* display driver knows that the BLT buffers will always be large */ 109971d7fec4Smrg /* enough to contain an entire scanline of a screen to screen BLT. */ 110071d7fec4Smrg 110171d7fec4Smrg if (dstx > srcx) { 110271d7fec4Smrg /* NEGATIVE X DIRECTION */ 110371d7fec4Smrg /* Still positive X direction within the section. */ 110471d7fec4Smrg 110571d7fec4Smrg srcx -= section; 110671d7fec4Smrg dstx -= section; 110771d7fec4Smrg WRITE_REG16(GP_SRC_XCOOR, srcx); 110871d7fec4Smrg WRITE_REG16(GP_DST_XCOOR, dstx); 110971d7fec4Smrg WRITE_REG16(GP_BLIT_MODE, blit_mode); 111071d7fec4Smrg } else { 111171d7fec4Smrg /* POSITIVE X DIRECTION */ 111271d7fec4Smrg 111371d7fec4Smrg WRITE_REG16(GP_SRC_XCOOR, srcx); 111471d7fec4Smrg WRITE_REG16(GP_DST_XCOOR, dstx); 111571d7fec4Smrg WRITE_REG16(GP_BLIT_MODE, blit_mode); 111671d7fec4Smrg dstx += section; 111771d7fec4Smrg srcx += section; 111871d7fec4Smrg } 111971d7fec4Smrg width -= section; 112071d7fec4Smrg } 112171d7fec4Smrg} 112271d7fec4Smrg 112371d7fec4Smrg/* 112471d7fec4Smrg//---------------------------------------------------------------------------- 112571d7fec4Smrg// COLOR BITMAP TO SCREEN BLT 112671d7fec4Smrg// 112771d7fec4Smrg// This routine transfers color bitmap data to the screen. For most cases, 112871d7fec4Smrg// when the ROP is SRCCOPY, it may be faster to write a separate routine that 112971d7fec4Smrg// copies the data to the frame buffer directly. This routine should be 113071d7fec4Smrg// used when the ROP requires destination data. 113171d7fec4Smrg// 113271d7fec4Smrg// Transparency is handled by another routine. 113371d7fec4Smrg// 113471d7fec4Smrg// SRCX X offset within source bitmap 113571d7fec4Smrg// SRCY Y offset within source bitmap 113671d7fec4Smrg// DSTX screen X position to render data 113771d7fec4Smrg// DSTY screen Y position to render data 113871d7fec4Smrg// WIDTH width of rectangle, in pixels 113971d7fec4Smrg// HEIGHT height of rectangle, in scanlines 114071d7fec4Smrg// *DATA pointer to bitmap data 114171d7fec4Smrg// PITCH pitch of bitmap data (bytes between scanlines) 114271d7fec4Smrg//---------------------------------------------------------------------------- 114371d7fec4Smrg*/ 114471d7fec4Smrg 114571d7fec4Smrg#if GFX_2DACCEL_DYNAMIC 114671d7fec4Smrgvoid 114771d7fec4Smrggu1_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, 114871d7fec4Smrg unsigned short dstx, unsigned short dsty, 114971d7fec4Smrg unsigned short width, unsigned short height, 115071d7fec4Smrg unsigned char *data, long pitch) 115171d7fec4Smrg#else 115271d7fec4Smrgvoid 115371d7fec4Smrggfx_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, 115471d7fec4Smrg unsigned short dstx, unsigned short dsty, 115571d7fec4Smrg unsigned short width, unsigned short height, 115671d7fec4Smrg unsigned char *data, long pitch) 115771d7fec4Smrg#endif 115871d7fec4Smrg{ 115971d7fec4Smrg unsigned short section, buffer_width; 116071d7fec4Smrg unsigned short blit_mode = BM_READ_SRC_BB0; 116171d7fec4Smrg unsigned short temp_height; 116271d7fec4Smrg unsigned long dword_bytes_needed, bytes_extra; 116371d7fec4Smrg unsigned long bpp_shift; 116471d7fec4Smrg long array_offset; 116571d7fec4Smrg 116671d7fec4Smrg /* CHECK SIZE OF BLT BUFFER */ 116771d7fec4Smrg 116871d7fec4Smrg buffer_width = GFXbufferWidthPixels; 116971d7fec4Smrg 117071d7fec4Smrg /* CHECK IF RASTER OPERATION REQUIRES DESTINATION DATA */ 117171d7fec4Smrg /* If no destination data, we have twice the room for */ 117271d7fec4Smrg /* source data. */ 117371d7fec4Smrg 117471d7fec4Smrg if (GFXusesDstData) 117571d7fec4Smrg blit_mode |= BM_READ_DST_FB1; 117671d7fec4Smrg else 117771d7fec4Smrg buffer_width <<= 1; 117871d7fec4Smrg 117971d7fec4Smrg /* SET THE SCRATCHPAD BASE */ 118071d7fec4Smrg 118171d7fec4Smrg SET_SCRATCH_BASE(GFXbb0Base); 118271d7fec4Smrg 118371d7fec4Smrg /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 118471d7fec4Smrg /* Write the registers that do not change for each section. */ 118571d7fec4Smrg 118671d7fec4Smrg GFX_WAIT_PENDING; 118771d7fec4Smrg WRITE_REG16(GP_HEIGHT, 1); 118871d7fec4Smrg 118971d7fec4Smrg bpp_shift = (GFXbpp + 7) >> 4; 119071d7fec4Smrg 119171d7fec4Smrg while (width > 0) { 119271d7fec4Smrg if (width > buffer_width) 119371d7fec4Smrg section = buffer_width; 119471d7fec4Smrg else 119571d7fec4Smrg section = width; 119671d7fec4Smrg 119771d7fec4Smrg dword_bytes_needed = (section << bpp_shift) & ~3l; 119871d7fec4Smrg bytes_extra = (section << bpp_shift) & 3l; 119971d7fec4Smrg 120071d7fec4Smrg temp_height = height; 120171d7fec4Smrg 120271d7fec4Smrg /* WRITE THE REGISTERS FOR EACH SECTION */ 120371d7fec4Smrg /* The GX hardware will auto-increment the Y coordinate, meaning */ 120471d7fec4Smrg /* that we don't have to. */ 120571d7fec4Smrg 120671d7fec4Smrg WRITE_REG16(GP_WIDTH, section); 120771d7fec4Smrg WRITE_REG16(GP_DST_XCOOR, dstx); 120871d7fec4Smrg WRITE_REG16(GP_DST_YCOOR, dsty); 120971d7fec4Smrg 121071d7fec4Smrg /* CALCULATE THE BITMAP OFFSET */ 121171d7fec4Smrg 121271d7fec4Smrg array_offset = 121371d7fec4Smrg (unsigned long)srcy *(long)pitch + ((long)srcx << bpp_shift); 121471d7fec4Smrg 121571d7fec4Smrg while (temp_height--) { 121671d7fec4Smrg GFX_WAIT_PIPELINE; 121771d7fec4Smrg 121871d7fec4Smrg /* WRITE ALL DATA TO THE BLT BUFFERS */ 121971d7fec4Smrg /* The WRITE_SCRATCH_STRING macro assumes that the data begins at the */ 122071d7fec4Smrg /* scratchpad offset set by the SET_SCRATCH_BASE macro. */ 122171d7fec4Smrg 122271d7fec4Smrg WRITE_SCRATCH_STRING(dword_bytes_needed, bytes_extra, data, 122371d7fec4Smrg array_offset); 122471d7fec4Smrg WRITE_REG16(GP_BLIT_MODE, blit_mode); 122571d7fec4Smrg 122671d7fec4Smrg array_offset += pitch; 122771d7fec4Smrg } 122871d7fec4Smrg 122971d7fec4Smrg width -= section; 123071d7fec4Smrg srcx += section; 123171d7fec4Smrg dstx += section; 123271d7fec4Smrg } 123371d7fec4Smrg} 123471d7fec4Smrg 123571d7fec4Smrg/* 123671d7fec4Smrg//---------------------------------------------------------------------------- 123771d7fec4Smrg// COLOR BITMAP TO SCREEN TRANSPARENT BLT 123871d7fec4Smrg// 123971d7fec4Smrg// This routine transfers color bitmap data to the screen with transparency. 124071d7fec4Smrg// The transparent color is specified. The only supported ROP is SRCCOPY, 124171d7fec4Smrg// meaning that transparency cannot be applied if the ROP requires 124271d7fec4Smrg// destination data (this is a hardware restriction). 124371d7fec4Smrg// 124471d7fec4Smrg// SRCX X offset within source bitmap 124571d7fec4Smrg// SRCY Y offset within source bitmap 124671d7fec4Smrg// DSTX screen X position to render data 124771d7fec4Smrg// DSTY screen Y position to render data 124871d7fec4Smrg// WIDTH width of rectangle, in pixels 124971d7fec4Smrg// HEIGHT height of rectangle, in scanlines 125071d7fec4Smrg// *DATA pointer to bitmap data 125171d7fec4Smrg// PITCH pitch of bitmap data (bytes between scanlines) 125271d7fec4Smrg// COLOR transparent color 125371d7fec4Smrg//---------------------------------------------------------------------------- 125471d7fec4Smrg*/ 125571d7fec4Smrg#if GFX_2DACCEL_DYNAMIC 125671d7fec4Smrgvoid 125771d7fec4Smrggu1_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy, 125871d7fec4Smrg unsigned short dstx, unsigned short dsty, 125971d7fec4Smrg unsigned short width, unsigned short height, 126071d7fec4Smrg unsigned char *data, long pitch, 126171d7fec4Smrg unsigned long color) 126271d7fec4Smrg#else 126371d7fec4Smrgvoid 126471d7fec4Smrggfx_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy, 126571d7fec4Smrg unsigned short dstx, unsigned short dsty, 126671d7fec4Smrg unsigned short width, unsigned short height, 126771d7fec4Smrg unsigned char *data, long pitch, 126871d7fec4Smrg unsigned long color) 126971d7fec4Smrg#endif 127071d7fec4Smrg{ 127171d7fec4Smrg unsigned short section, buffer_width; 127271d7fec4Smrg unsigned short temp_height; 127371d7fec4Smrg unsigned long dword_bytes_needed, bytes_extra; 127471d7fec4Smrg unsigned long bpp_shift; 127571d7fec4Smrg long array_offset; 127671d7fec4Smrg 127771d7fec4Smrg /* CHECK SIZE OF BLT BUFFER */ 127871d7fec4Smrg 127971d7fec4Smrg buffer_width = GFXbufferWidthPixels; 128071d7fec4Smrg 128171d7fec4Smrg /* WRITE TRANSPARENCY COLOR TO BLT BUFFER 1 */ 128271d7fec4Smrg 128371d7fec4Smrg if (GFXbpp == 8) { 128471d7fec4Smrg color &= 0x00FF; 128571d7fec4Smrg color |= (color << 8); 128671d7fec4Smrg } 128771d7fec4Smrg color = (color & 0x0000FFFF) | (color << 16); 128871d7fec4Smrg 128971d7fec4Smrg /* WAIT UNTIL PIPELINE IS NOT BUSY BEFORE LOADING DATA INTO BB1 */ 129071d7fec4Smrg /* Need to make sure any previous BLT using BB1 is complete. */ 129171d7fec4Smrg /* Only need to load 32 bits of BB1 for the 1 pixel BLT that follows. */ 129271d7fec4Smrg 129371d7fec4Smrg GFX_WAIT_PIPELINE; 129471d7fec4Smrg GFX_WAIT_PENDING; 129571d7fec4Smrg WRITE_SCRATCH32(GFXbb1Base, color); 129671d7fec4Smrg 129771d7fec4Smrg /* DO BOGUS BLT TO LATCH DATA FROM BB1 */ 129871d7fec4Smrg /* Already know graphics pipeline is idle. */ 129971d7fec4Smrg /* Only need to latch data into the holding registers for the current */ 130071d7fec4Smrg /* data from BB1. A 1 pixel wide BLT will suffice. */ 130171d7fec4Smrg 130271d7fec4Smrg WRITE_REG32(GP_DST_XCOOR, 0); 130371d7fec4Smrg WRITE_REG32(GP_SRC_XCOOR, 0); 130471d7fec4Smrg WRITE_REG32(GP_WIDTH, 0x00010001); 130571d7fec4Smrg WRITE_REG16(GP_RASTER_MODE, 0x00CC); 130671d7fec4Smrg WRITE_REG16(GP_BLIT_MODE, BM_READ_SRC_FB | BM_READ_DST_BB1); 130771d7fec4Smrg 130871d7fec4Smrg /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 130971d7fec4Smrg /* Write the registers that do not change for each section. */ 131071d7fec4Smrg 131171d7fec4Smrg GFX_WAIT_PENDING; 131271d7fec4Smrg WRITE_REG16(GP_HEIGHT, 1); 131371d7fec4Smrg WRITE_REG16(GP_RASTER_MODE, 0x10C6); 131471d7fec4Smrg WRITE_REG32(GP_PAT_COLOR_0, 0xFFFFFFFF); 131571d7fec4Smrg 131671d7fec4Smrg bpp_shift = (GFXbpp + 7) >> 4; 131771d7fec4Smrg 131871d7fec4Smrg /* SET THE SCRATCHPAD BASE */ 131971d7fec4Smrg 132071d7fec4Smrg SET_SCRATCH_BASE(GFXbb0Base); 132171d7fec4Smrg 132271d7fec4Smrg while (width > 0) { 132371d7fec4Smrg if (width > buffer_width) 132471d7fec4Smrg section = buffer_width; 132571d7fec4Smrg else 132671d7fec4Smrg section = width; 132771d7fec4Smrg 132871d7fec4Smrg dword_bytes_needed = (section << bpp_shift) & ~3l; 132971d7fec4Smrg bytes_extra = (section << bpp_shift) & 3l; 133071d7fec4Smrg 133171d7fec4Smrg temp_height = height; 133271d7fec4Smrg 133371d7fec4Smrg /* WRITE THE REGISTERS FOR EACH SECTION */ 133471d7fec4Smrg /* The GX hardware will auto-increment the Y coordinate, meaning */ 133571d7fec4Smrg /* that we don't have to. */ 133671d7fec4Smrg 133771d7fec4Smrg WRITE_REG16(GP_WIDTH, section); 133871d7fec4Smrg WRITE_REG16(GP_DST_XCOOR, dstx); 133971d7fec4Smrg WRITE_REG16(GP_DST_YCOOR, dsty); 134071d7fec4Smrg 134171d7fec4Smrg /* CALCULATE THE BITMAP OFFSET */ 134271d7fec4Smrg 134371d7fec4Smrg array_offset = 134471d7fec4Smrg (unsigned long)srcy *(long)pitch + ((long)srcx << bpp_shift); 134571d7fec4Smrg 134671d7fec4Smrg while (temp_height--) { 134771d7fec4Smrg GFX_WAIT_PIPELINE; 134871d7fec4Smrg 134971d7fec4Smrg /* WRITE ALL DATA TO THE BLT BUFFERS */ 135071d7fec4Smrg /* The WRITE_SCRATCH_STRING macro assumes that the data begins at the */ 135171d7fec4Smrg /* scratchpad offset set by the SET_SCRATCH_BASE macro. */ 135271d7fec4Smrg 135371d7fec4Smrg WRITE_SCRATCH_STRING(dword_bytes_needed, bytes_extra, data, 135471d7fec4Smrg array_offset); 135571d7fec4Smrg WRITE_REG16(GP_BLIT_MODE, BM_READ_SRC_BB0); 135671d7fec4Smrg 135771d7fec4Smrg array_offset += pitch; 135871d7fec4Smrg } 135971d7fec4Smrg 136071d7fec4Smrg width -= section; 136171d7fec4Smrg srcx += section; 136271d7fec4Smrg dstx += section; 136371d7fec4Smrg } 136471d7fec4Smrg} 136571d7fec4Smrg 136671d7fec4Smrg/* 136771d7fec4Smrg//---------------------------------------------------------------------------- 136871d7fec4Smrg// MONOCHROME BITMAP TO SCREEN BLT 136971d7fec4Smrg// 137071d7fec4Smrg// This routine transfers monochrome bitmap data to the screen. 137171d7fec4Smrg// 137271d7fec4Smrg// SRCX X offset within source bitmap 137371d7fec4Smrg// SRCY Y offset within source bitmap 137471d7fec4Smrg// DSTX screen X position to render data 137571d7fec4Smrg// DSTY screen Y position to render data 137671d7fec4Smrg// WIDTH width of rectangle, in pixels 137771d7fec4Smrg// HEIGHT height of rectangle, in scanlines 137871d7fec4Smrg// *DATA pointer to bitmap data 137971d7fec4Smrg// PITCH pitch of bitmap data (bytes between scanlines) 138071d7fec4Smrg//---------------------------------------------------------------------------- 138171d7fec4Smrg*/ 138271d7fec4Smrg#if GFX_2DACCEL_DYNAMIC 138371d7fec4Smrgvoid 138471d7fec4Smrggu1_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, 138571d7fec4Smrg unsigned short dstx, unsigned short dsty, 138671d7fec4Smrg unsigned short width, unsigned short height, 138771d7fec4Smrg unsigned char *data, short pitch) 138871d7fec4Smrg#else 138971d7fec4Smrgvoid 139071d7fec4Smrggfx_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, 139171d7fec4Smrg unsigned short dstx, unsigned short dsty, 139271d7fec4Smrg unsigned short width, unsigned short height, 139371d7fec4Smrg unsigned char *data, short pitch) 139471d7fec4Smrg#endif 139571d7fec4Smrg{ 139671d7fec4Smrg unsigned short section, buffer_width; 139771d7fec4Smrg unsigned short blit_mode = BM_READ_SRC_BB0 | BM_SOURCE_EXPAND; 139871d7fec4Smrg unsigned short temp_height; 139971d7fec4Smrg unsigned long dword_bytes_needed, bytes_extra; 140071d7fec4Smrg long array_offset; 140171d7fec4Smrg 140271d7fec4Smrg /* CHECK IF RASTER OPERATION REQUIRES DESTINATION DATA */ 140371d7fec4Smrg /* If no destination data, the source data will always fit. */ 140471d7fec4Smrg /* So, in that event we will set the buffer width to a */ 140571d7fec4Smrg /* fictitiously large value such that the BLT is never split. */ 140671d7fec4Smrg 140771d7fec4Smrg if (GFXusesDstData) { 140871d7fec4Smrg buffer_width = GFXbufferWidthPixels; 140971d7fec4Smrg blit_mode |= BM_READ_DST_FB1; 141071d7fec4Smrg } else 141171d7fec4Smrg buffer_width = 3200; 141271d7fec4Smrg 141371d7fec4Smrg /* CHECK IF DATA ALREADY IN BLIT BUFFER */ 141471d7fec4Smrg /* If the pointer is NULL, data for the full BLT is already there */ 141571d7fec4Smrg /* WARNING: This could cause problems if destination data is */ 141671d7fec4Smrg /* involved and it overflows the BLT buffer. Need to remove */ 141771d7fec4Smrg /* this option and change the drivers to use a temporary buffer. */ 141871d7fec4Smrg 141971d7fec4Smrg if (!data) { 142071d7fec4Smrg GFX_WAIT_PENDING; 142171d7fec4Smrg WRITE_REG16(GP_SRC_XCOOR, srcx & 7); 142271d7fec4Smrg WRITE_REG16(GP_DST_XCOOR, dstx); 142371d7fec4Smrg WRITE_REG16(GP_DST_YCOOR, dsty); 142471d7fec4Smrg WRITE_REG16(GP_WIDTH, width); 142571d7fec4Smrg WRITE_REG16(GP_HEIGHT, height); 142671d7fec4Smrg WRITE_REG16(GP_BLIT_MODE, blit_mode); 142771d7fec4Smrg return; 142871d7fec4Smrg } 142971d7fec4Smrg 143071d7fec4Smrg /* SET THE SCRATCHPAD BASE */ 143171d7fec4Smrg 143271d7fec4Smrg SET_SCRATCH_BASE(GFXbb0Base); 143371d7fec4Smrg 143471d7fec4Smrg /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 143571d7fec4Smrg /* Write the registers that do not change for each section. */ 143671d7fec4Smrg 143771d7fec4Smrg GFX_WAIT_PENDING; 143871d7fec4Smrg WRITE_REG16(GP_HEIGHT, 1); 143971d7fec4Smrg 144071d7fec4Smrg while (width > 0) { 144171d7fec4Smrg if (width > buffer_width) 144271d7fec4Smrg section = buffer_width; 144371d7fec4Smrg else 144471d7fec4Smrg section = width; 144571d7fec4Smrg 144671d7fec4Smrg /* CALCULATE BYTES NEEDED */ 144771d7fec4Smrg /* Add 1 for possible alignment issues. */ 144871d7fec4Smrg 144971d7fec4Smrg dword_bytes_needed = ((section + 7 + (srcx & 7)) >> 3) & ~3l; 145071d7fec4Smrg bytes_extra = ((section + 7 + (srcx & 7)) >> 3) & 3l; 145171d7fec4Smrg 145271d7fec4Smrg temp_height = height; 145371d7fec4Smrg 145471d7fec4Smrg /* WRITE THE REGISTERS FOR EACH SECTION */ 145571d7fec4Smrg /* The GX hardware will auto-increment the Y coordinate, meaning */ 145671d7fec4Smrg /* that we don't have to. */ 145771d7fec4Smrg 145871d7fec4Smrg WRITE_REG16(GP_WIDTH, section); 145971d7fec4Smrg WRITE_REG16(GP_DST_XCOOR, dstx); 146071d7fec4Smrg WRITE_REG16(GP_DST_YCOOR, dsty); 146171d7fec4Smrg WRITE_REG16(GP_SRC_XCOOR, srcx & 7); 146271d7fec4Smrg 146371d7fec4Smrg /* CALCULATE THE BITMAP OFFSET */ 146471d7fec4Smrg 146571d7fec4Smrg array_offset = (unsigned long)srcy *(long)pitch + ((long)srcx >> 3); 146671d7fec4Smrg 146771d7fec4Smrg while (temp_height--) { 146871d7fec4Smrg GFX_WAIT_PIPELINE; 146971d7fec4Smrg 147071d7fec4Smrg /* WRITE ALL DATA TO THE BLT BUFFERS */ 147171d7fec4Smrg /* The WRITE_SCRATCH_STRING macro assumes that the data begins at the */ 147271d7fec4Smrg /* scratchpad offset set by the SET_SCRATCH_BASE macro. */ 147371d7fec4Smrg 147471d7fec4Smrg WRITE_SCRATCH_STRING(dword_bytes_needed, bytes_extra, data, 147571d7fec4Smrg array_offset); 147671d7fec4Smrg WRITE_REG16(GP_BLIT_MODE, blit_mode); 147771d7fec4Smrg 147871d7fec4Smrg array_offset += pitch; 147971d7fec4Smrg } 148071d7fec4Smrg 148171d7fec4Smrg width -= section; 148271d7fec4Smrg srcx += section; 148371d7fec4Smrg dstx += section; 148471d7fec4Smrg } 148571d7fec4Smrg} 148671d7fec4Smrg 148771d7fec4Smrg/* 148871d7fec4Smrg//---------------------------------------------------------------------------- 148971d7fec4Smrg// MONOCHROME TEXT BLT 149071d7fec4Smrg// 149171d7fec4Smrg// This routine transfers contiguous monochrome text data to the screen. 149271d7fec4Smrg// 149371d7fec4Smrg// DSTX screen X position to render data 149471d7fec4Smrg// DSTY screen Y position to render data 149571d7fec4Smrg// WIDTH width of rectangle, in pixels 149671d7fec4Smrg// HEIGHT height of rectangle, in scanlines 149771d7fec4Smrg// *DATA pointer to bitmap data 149871d7fec4Smrg//---------------------------------------------------------------------------- 149971d7fec4Smrg*/ 150071d7fec4Smrg#if GFX_2DACCEL_DYNAMIC 150171d7fec4Smrgvoid 150271d7fec4Smrggu1_text_blt(unsigned short dstx, unsigned short dsty, unsigned short width, 150371d7fec4Smrg unsigned short height, unsigned char *data) 150471d7fec4Smrg#else 150571d7fec4Smrgvoid 150671d7fec4Smrggfx_text_blt(unsigned short dstx, unsigned short dsty, unsigned short width, 150771d7fec4Smrg unsigned short height, unsigned char *data) 150871d7fec4Smrg#endif 150971d7fec4Smrg{ 151071d7fec4Smrg unsigned long dword_bytes_needed, bytes_extra; 151171d7fec4Smrg long pitch, buffer_bytes, data_bytes; 151271d7fec4Smrg 151371d7fec4Smrg /* CALCULATE DATA SIZE */ 151471d7fec4Smrg 151571d7fec4Smrg pitch = (width + 7) >> 3; 151671d7fec4Smrg data_bytes = (long)height *pitch; 151771d7fec4Smrg 151871d7fec4Smrg /* CHECK FOR SIMPLE CASE */ 151971d7fec4Smrg /* This routine is designed to render a source copy text glyph. If destination */ 152071d7fec4Smrg /* data is required or the source data will not fit, we will punt the operation */ 152171d7fec4Smrg /* to the more versatile (and slow) mono bitmap routine. */ 152271d7fec4Smrg 152371d7fec4Smrg if (GFXbpp > 8) 152471d7fec4Smrg buffer_bytes = GFXbufferWidthPixels << 1; 152571d7fec4Smrg else 152671d7fec4Smrg buffer_bytes = GFXbufferWidthPixels; 152771d7fec4Smrg 152871d7fec4Smrg if (GFXusesDstData || data_bytes > buffer_bytes) { 152971d7fec4Smrg gfx_mono_bitmap_to_screen_blt(0, 0, dstx, dsty, width, height, data, 153071d7fec4Smrg (short)pitch); 153171d7fec4Smrg return; 153271d7fec4Smrg } 153371d7fec4Smrg 153471d7fec4Smrg /* SET THE SCRATCHPAD BASE */ 153571d7fec4Smrg 153671d7fec4Smrg SET_SCRATCH_BASE(GFXbb0Base); 153771d7fec4Smrg 153871d7fec4Smrg /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 153971d7fec4Smrg 154071d7fec4Smrg dword_bytes_needed = data_bytes & ~3l; 154171d7fec4Smrg bytes_extra = data_bytes & 3l; 154271d7fec4Smrg 154371d7fec4Smrg GFX_WAIT_PENDING; 154471d7fec4Smrg WRITE_REG16(GP_HEIGHT, height); 154571d7fec4Smrg WRITE_REG16(GP_WIDTH, width); 154671d7fec4Smrg WRITE_REG16(GP_DST_XCOOR, dstx); 154771d7fec4Smrg WRITE_REG16(GP_DST_YCOOR, dsty); 154871d7fec4Smrg WRITE_REG16(GP_SRC_XCOOR, 0); 154971d7fec4Smrg 155071d7fec4Smrg /* WRITE ALL DATA TO THE BLT BUFFERS */ 155171d7fec4Smrg /* The WRITE_SCRATCH_STRING macro assumes that the data begins at the */ 155271d7fec4Smrg /* scratchpad offset set by the SET_SCRATCH_BASE macro. */ 155371d7fec4Smrg 155471d7fec4Smrg GFX_WAIT_PIPELINE; 155571d7fec4Smrg 155671d7fec4Smrg WRITE_SCRATCH_STRING(dword_bytes_needed, bytes_extra, data, 0); 155771d7fec4Smrg WRITE_REG16(GP_BLIT_MODE, BM_READ_SRC_BB0 | BM_SOURCE_TEXT); 155871d7fec4Smrg} 155971d7fec4Smrg 156071d7fec4Smrg/* 156171d7fec4Smrg//---------------------------------------------------------------------------- 156271d7fec4Smrg// BRESENHAM LINE 156371d7fec4Smrg// 156471d7fec4Smrg// This routine draws a vector using the specified Bresenham parameters. 156571d7fec4Smrg// Currently this file does not support a routine that accepts the two 156671d7fec4Smrg// endpoints of a vector and calculates the Bresenham parameters. If it 156771d7fec4Smrg// ever does, this routine is still required for vectors that have been 156871d7fec4Smrg// clipped. 156971d7fec4Smrg// 157071d7fec4Smrg// X screen X position to start vector 157171d7fec4Smrg// Y screen Y position to start vector 157271d7fec4Smrg// LENGTH length of the vector, in pixels 157371d7fec4Smrg// INITERR Bresenham initial error term 157471d7fec4Smrg// AXIALERR Bresenham axial error term 157571d7fec4Smrg// DIAGERR Bresenham diagonal error term 157671d7fec4Smrg// FLAGS VM_YMAJOR, VM_MAJOR_INC, VM_MINOR_INC 157771d7fec4Smrg//---------------------------------------------------------------------------- 157871d7fec4Smrg*/ 157971d7fec4Smrg#if GFX_2DACCEL_DYNAMIC 158071d7fec4Smrgvoid 158171d7fec4Smrggu1_bresenham_line(unsigned short x, unsigned short y, 158271d7fec4Smrg unsigned short length, unsigned short initerr, 158371d7fec4Smrg unsigned short axialerr, unsigned short diagerr, 158471d7fec4Smrg unsigned short flags) 158571d7fec4Smrg#else 158671d7fec4Smrgvoid 158771d7fec4Smrggfx_bresenham_line(unsigned short x, unsigned short y, 158871d7fec4Smrg unsigned short length, unsigned short initerr, 158971d7fec4Smrg unsigned short axialerr, unsigned short diagerr, 159071d7fec4Smrg unsigned short flags) 159171d7fec4Smrg#endif 159271d7fec4Smrg{ 159371d7fec4Smrg unsigned short vector_mode = flags; 159471d7fec4Smrg 159571d7fec4Smrg if (GFXusesDstData) 159671d7fec4Smrg vector_mode |= VM_READ_DST_FB; 159771d7fec4Smrg 159871d7fec4Smrg /* CHECK NULL LENGTH */ 159971d7fec4Smrg 160071d7fec4Smrg if (!length) 160171d7fec4Smrg return; 160271d7fec4Smrg 160371d7fec4Smrg /* LOAD THE REGISTERS FOR THE VECTOR */ 160471d7fec4Smrg 160571d7fec4Smrg GFX_WAIT_PENDING; 160671d7fec4Smrg WRITE_REG16(GP_DST_XCOOR, x); 160771d7fec4Smrg WRITE_REG16(GP_DST_YCOOR, y); 160871d7fec4Smrg WRITE_REG16(GP_VECTOR_LENGTH, length); 160971d7fec4Smrg WRITE_REG16(GP_INIT_ERROR, initerr); 161071d7fec4Smrg WRITE_REG16(GP_AXIAL_ERROR, axialerr); 161171d7fec4Smrg WRITE_REG16(GP_DIAG_ERROR, diagerr); 161271d7fec4Smrg WRITE_REG16(GP_VECTOR_MODE, vector_mode); 161371d7fec4Smrg} 161471d7fec4Smrg 161571d7fec4Smrg/*--------------------------------------------------------------------------- 161671d7fec4Smrg * GFX_WAIT_UNTIL_IDLE 161771d7fec4Smrg * 161871d7fec4Smrg * This routine waits until the graphics engine is idle. This is required 161971d7fec4Smrg * before allowing direct access to the frame buffer. 162071d7fec4Smrg *--------------------------------------------------------------------------- 162171d7fec4Smrg */ 162271d7fec4Smrg#if GFX_2DACCEL_DYNAMIC 162371d7fec4Smrgvoid 162471d7fec4Smrggu1_wait_until_idle(void) 162571d7fec4Smrg#else 162671d7fec4Smrgvoid 162771d7fec4Smrggfx_wait_until_idle(void) 162871d7fec4Smrg#endif 162971d7fec4Smrg{ 163071d7fec4Smrg GFX_WAIT_BUSY; 163171d7fec4Smrg} 163271d7fec4Smrg 163371d7fec4Smrg/*--------------------------------------------------------------------------- 163471d7fec4Smrg * GFX_TEST_BLT_PENDING 163571d7fec4Smrg * 163671d7fec4Smrg * This routine returns 1 if a BLT is pending, meaning that a call to 163771d7fec4Smrg * perform a rendering operation would stall. Otherwise it returns 0. 163871d7fec4Smrg * It is used by Darwin during random testing to only start a BLT 163971d7fec4Smrg * operation when it knows the Durango routines won't spin on graphics 164071d7fec4Smrg * (so Darwin can continue to do frame buffer reads and writes). 164171d7fec4Smrg *--------------------------------------------------------------------------- 164271d7fec4Smrg */ 164371d7fec4Smrg#if GFX_2DACCEL_DYNAMIC 164471d7fec4Smrgint 164571d7fec4Smrggu1_test_blt_pending(void) 164671d7fec4Smrg#else 164771d7fec4Smrgint 164871d7fec4Smrggfx_test_blt_pending(void) 164971d7fec4Smrg#endif 165071d7fec4Smrg{ 165171d7fec4Smrg if (READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING) 165271d7fec4Smrg return (1); 165371d7fec4Smrg else 165471d7fec4Smrg return (0); 165571d7fec4Smrg} 165671d7fec4Smrg 165771d7fec4Smrg/*--------------------------------------------------------------------------- 165871d7fec4Smrg * BLT BUFFERS!!!!! 165971d7fec4Smrg *--------------------------------------------------------------------------- 166071d7fec4Smrg */ 166171d7fec4Smrg 166271d7fec4Smrg/* THE BOOT CODE MUST SET THE BLT BUFFER BASES USING THE "CPU_WRITE" */ 166371d7fec4Smrg/* INSTRUCTION TO ONE OF THE FOLLOWING VALUES: */ 166471d7fec4Smrg 166571d7fec4Smrg#define BB0_BASE_2K 0x800 166671d7fec4Smrg#define BB1_BASE_2K 0xB30 166771d7fec4Smrg#define BB0_BASE_3K 0x400 166871d7fec4Smrg#define BB1_BASE_3K 0x930 166971d7fec4Smrg 167071d7fec4Smrg/*--------------------------------------------------------------------------- 167171d7fec4Smrg * gu1_detect_blt_buffer_base 167271d7fec4Smrg * 167371d7fec4Smrg * This detection is hidden from the driver by being called from the 167471d7fec4Smrg * "gfx_set_bpp" routine. 167571d7fec4Smrg * 167671d7fec4Smrg * This is fairly ugly for the following reasons: 167771d7fec4Smrg * 167871d7fec4Smrg * - It is the boot code that must set the BLT buffer bases to the 167971d7fec4Smrg * appropriate values and load the scratchpad tags. 168071d7fec4Smrg * - The old drivers would also set the base address values to what they 168171d7fec4Smrg * knew they should be for the 2K or 3K scratchpad configuration. 168271d7fec4Smrg * - Unfortunately, to set the base addresses requires the use of the 168371d7fec4Smrg * CPU_WRITE instruction, an instruction specific to GX. 168471d7fec4Smrg * - Using the CPU_WRITE instruction requires the use of assembly to 168571d7fec4Smrg * produce the appropriate op codes. 168671d7fec4Smrg * - Assembly is something that is avoided in Durango because it is not 168771d7fec4Smrg * platform independent. Some compilers do not support inline assembly. 168871d7fec4Smrg * - Therefore Durango cannot use the CPU_WRITE instruction. 168971d7fec4Smrg * - Therefore drivers using Durango must rely on the boot code to set 169071d7fec4Smrg * the appropriate values. Durango uses this routine to check where 169171d7fec4Smrg * the base addresses have been set. 169271d7fec4Smrg * - Unfortunately, it is not as simple as using IO to check for 2K or 3K 169371d7fec4Smrg * scratchpad size. In VSA1, even though the boot code may set it for 169471d7fec4Smrg * 3K, SoftVGA comes along and resets it to 2K for it's use in text 169571d7fec4Smrg * redraws. It used to be that the display driver would set it back 169671d7fec4Smrg * to 3K. 169771d7fec4Smrg * - So, the Durango code was changed to just always use 2K. 169871d7fec4Smrg * - But, the XpressROM code sets it for 3K, and the newer versions of 169971d7fec4Smrg * SoftVGA do not interfere with that, so then Durango needs to use 170071d7fec4Smrg * the 3K values to work properly. 170171d7fec4Smrg * - Therefore, Durango does somewhat of a kludge by writing to directly 170271d7fec4Smrg * to the scratchpad at both the 2K and 3K locations, then performing 170371d7fec4Smrg * a unobtrusive BLT that loads data into BB0 (the graphics engine 170471d7fec4Smrg * always knows the true base). After the BLT, Durango looks to see 170571d7fec4Smrg * which location changed to know where the base address is. 170671d7fec4Smrg * - This is a relatively simple way to allow Durango to work on old 170771d7fec4Smrg * and new platforms without using theCPU_WRITE instructions. 170871d7fec4Smrg * 170971d7fec4Smrg * To summarize, the BLT buffers are one of the most painful aspects of 171071d7fec4Smrg * the GX graphics unit design, and have been removed from future designs 171171d7fec4Smrg * (the graphics unit has its own dedicated RAM). Durango has tried to 171271d7fec4Smrg * hide the BLT buffer use from the drivers. 171371d7fec4Smrg *--------------------------------------------------------------------------- 171471d7fec4Smrg */ 171571d7fec4Smrgvoid 171671d7fec4Smrggu1_detect_blt_buffer_base(void) 171771d7fec4Smrg{ 171871d7fec4Smrg /* ASSUME 2K */ 171971d7fec4Smrg 172071d7fec4Smrg GFXbb0Base = BB0_BASE_2K; 172171d7fec4Smrg GFXbb1Base = BB1_BASE_2K; 172271d7fec4Smrg 172371d7fec4Smrg /* CHECK IF SCRATCHPAD IS SET TO 3K OR 4K */ 172471d7fec4Smrg /* Boot code should still set 3K values for 4K. */ 172571d7fec4Smrg 172671d7fec4Smrg if (gfx_gxm_config_read(GXM_CONFIG_GCR) & 0x08) { 172771d7fec4Smrg /* WRITE DATA TO 3K LOCATION */ 172871d7fec4Smrg 172971d7fec4Smrg GFX_WAIT_BUSY; 173071d7fec4Smrg WRITE_SCRATCH32(BB0_BASE_3K, 0xFEEDFACE); 173171d7fec4Smrg 173271d7fec4Smrg /* HAVE THE GRAPHICS UNIT STORE SOMETHING IN BB0 */ 173371d7fec4Smrg 173471d7fec4Smrg WRITE_REG32(GP_DST_XCOOR, 0x00000000); /* AT (0,0) */ 173571d7fec4Smrg WRITE_REG32(GP_WIDTH, 0x00010004); /* 4x1 BLT */ 173671d7fec4Smrg WRITE_REG16(GP_RASTER_MODE, 0x00AA); /* KEEP DST */ 173771d7fec4Smrg WRITE_REG16(GP_BLIT_MODE, BM_READ_DST_FB0); /* STORE IN BB0 */ 173871d7fec4Smrg 173971d7fec4Smrg /* CHECK 3K LOCATION */ 174071d7fec4Smrg /* Breaks if data happened to be 0xFEEDFACE - unlikely. */ 174171d7fec4Smrg 174271d7fec4Smrg GFX_WAIT_BUSY; 174371d7fec4Smrg if (READ_SCRATCH32(BB0_BASE_3K) != 0xFEEDFACE) { 174471d7fec4Smrg GFXbb0Base = BB0_BASE_3K; 174571d7fec4Smrg GFXbb1Base = BB1_BASE_3K; 174671d7fec4Smrg } 174771d7fec4Smrg } 174871d7fec4Smrg} 174971d7fec4Smrg 175071d7fec4Smrg/* END OF FILE */ 1751