diff options
Diffstat (limited to 'Source/DirectFB/gfxdrivers/cyber5k/cyber5k_overlay.c')
-rwxr-xr-x | Source/DirectFB/gfxdrivers/cyber5k/cyber5k_overlay.c | 376 |
1 files changed, 376 insertions, 0 deletions
diff --git a/Source/DirectFB/gfxdrivers/cyber5k/cyber5k_overlay.c b/Source/DirectFB/gfxdrivers/cyber5k/cyber5k_overlay.c new file mode 100755 index 0000000..b4638df --- /dev/null +++ b/Source/DirectFB/gfxdrivers/cyber5k/cyber5k_overlay.c @@ -0,0 +1,376 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp <dok@directfb.org>, + Andreas Hundt <andi@fischlustig.de>, + Sven Neumann <neo@directfb.org>, + Ville Syrjälä <syrjala@sci.fi> and + Claudio Ciccani <klan@users.sf.net>. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <directfb.h> + +#include <core/coredefs.h> + +#include "cyber5k.h" +#include "cyber5k_overlay.h" +#include "regs.h" +#include "mmio.h" + +static int overlay_byte_per_pixel = 2; +static int overlay_init = 0; + +static unsigned char savedReg74, savedReg75; /*FIFO control registers for 2D Graphics*/ +static unsigned char savedRegD9[2], savedRegDA[2], savedRegDD[2]; /*FIFO control registers for Overlay*/ +/*Following is our FIFO policy number, should be programmed to +0x3CE/0x74, 0x3CE/0x75, 0x3CE(0x3C4)/0xD9, 0x3CE(0x3C4)/0xDA, +0x3CE(0x3c4)/0xDD respectively in order to get a best memory bandwidth. +Current value is a group of experence value based on 70MHZ EDO/SG RAM.*/ +static unsigned char bFIFOPolicyNum[5] = {0x10, 0x10, 0x1C, 0x1C, 0x06}; + + +static void +cyber_videoreg_mask( unsigned char index, unsigned char value, unsigned char mask ) +{ + unsigned char tmp; + + cyber_out8( cyber_mmio, GRAINDEX, index ); + tmp = cyber_in8( cyber_mmio, GRADATA ); + tmp &= mask; + tmp |= value; + cyber_out8( cyber_mmio, GRADATA, tmp ); +} + +static void +cyber_seqreg_mask( unsigned char index, unsigned char value, unsigned char mask ) +{ + unsigned char tmp; + + cyber_out8( cyber_mmio, SEQINDEX, index ); + tmp = cyber_in8( cyber_mmio, SEQDATA ); + + tmp &= mask; + tmp |= value; + cyber_out8( cyber_mmio, SEQDATA, tmp ); +} + +static void +cyber_overlayreg_mask( unsigned char index, unsigned char value, unsigned char mask ) { + unsigned char tmp; + + cyber_out8( cyber_mmio, GRAINDEX, index ); + tmp = cyber_in8( cyber_mmio, GRADATA ); + + tmp &= mask; + tmp |= value; + cyber_out8(cyber_mmio, GRADATA, tmp); +} + +void cyber_cleanup_overlay(void) +{ + /*restore FIFO control regs*/ + cyber_seqreg_mask(0xA7, 0x0, ~0x5); + + + if (!overlay_init) + return; + overlay_init = 0; + + + cyber_grphw(0x74, savedReg74); + cyber_grphw(0x75, savedReg75); + + cyber_grphw(0xD9, savedRegD9[0]); + cyber_grphw(0xDA, savedRegDA[0]); + cyber_grphw(0xDD, savedRegDD[0]); + + cyber_seqw(0xD9, savedRegD9[1]); + cyber_seqw(0xDA, savedRegDA[1]); + cyber_seqw(0xDD, savedRegDD[1]); +} + +void cyber_init_overlay(void) +{ + /*Clear Overlay path first*/ + cyber_grphw(DISP_CTL_I, 0x00); + + /* Video Display Vertical Starting Line (may not need initiate here)*/ + cyber_grphw(DEST_RECT_TOP_L, 0x00); + cyber_grphw(DEST_RECT_TOP_H, 0x00); + + /* Overlay Vertical DDA Increment Value*/ + cyber_grphw(DDA_Y_INC_L, 0x00); + cyber_grphw(DDA_Y_INC_H, 0x10); + + /* Video Memory Starting Address*/ + cyber_grphw(MEMORY_START_L, 0x00); + cyber_grphw(MEMORY_START_M, 0x0f); + cyber_grphw(MEMORY_START_H, 0x03); /* Temporary fixed to 0x30f00 = 0xc3c00 >> 2*/ + /* 0x3c00 = 0x300*0x14 = 768*20*/ + + /* Video Display Horizontal Starting Pixel -- may not need init here*/ + cyber_grphw(DEST_RECT_LEFT_L, 0x20); + cyber_grphw(DEST_RECT_LEFT_H, 0x00); + + /* Video Display Horizontal Ending Pixel -- may not need init here*/ + cyber_grphw(DEST_RECT_RIGHT_L, 0x60); + cyber_grphw(DEST_RECT_RIGHT_H, 0x01); + + /* Video Display Vertical Ending Line -- may not need init here*/ + cyber_grphw(DEST_RECT_BOTTOM_L, 0xe0); + cyber_grphw(DEST_RECT_BOTTOM_H, 0x00); + + /* Video Color Compare Register*/ + cyber_grphw(COLOR_CMP_RED, 0x00); + cyber_grphw(COLOR_CMP_GREEN,0x00); + cyber_grphw(COLOR_CMP_BLUE, 0x00); + + /* Video Horizontal DDA Increment Value*/ + cyber_grphw(DDA_X_INC_L, 0x00); + cyber_grphw(DDA_X_INC_H, 0x10); + + /* Video Format Control*/ + cyber_grphw(VIDEO_FORMAT, 0x00); + + /* Video Misc Control*/ + cyber_grphw(MISC_CTL_I, 0x00); + + cyber_grphw(MISC_CTL_I, 0x01); /* Video Misc Control*/ + + /*default to colorkey*/ + cyber_grphw(DISP_CTL_I, 0x04 ); + +#ifdef NTSCTVOUT /*if your TV output mode is NTSC*/ + cyber_seqreg_mask(0xA6, 0x20, ~0x30); +#else /*if your TV output mode is PAL*/ + cyber_seqreg_mask(0xA6, 0x30, ~0x30); +#endif + + + if (overlay_init) + return; + overlay_init = 1; + + + +/* the following code is commented out, since saved values are not clean if */ +/* DirectFB crashed while underlay was enabled, hardcoded bootup */ +/* values instead (see below) */ + +/* + cyber_out8(cyber_mmio, GRAINDEX, 0x74); + savedReg74 = cyber_in8(cyber_mmio, GRADATA); + cyber_out8(cyber_mmio, GRAINDEX, 0x75); + savedReg75 = cyber_in8(cyber_mmio, GRADATA); + + cyber_out8(cyber_mmio, GRAINDEX, 0xD9); + savedRegD9[0] = cyber_in8(cyber_mmio, GRADATA); + cyber_out8(cyber_mmio, GRAINDEX, 0xDA); + savedRegDA[0] = cyber_in8(cyber_mmio, GRADATA); + cyber_out8(cyber_mmio, GRAINDEX, 0xDD); + savedRegDD[0] = cyber_in8(cyber_mmio, GRADATA); + + cyber_out8(cyber_mmio, SEQINDEX, 0xD9); + savedRegD9[1] = cyber_in8(cyber_mmio, SEQDATA); + cyber_out8(cyber_mmio, SEQINDEX, 0xDA); + savedRegDA[1] = cyber_in8(cyber_mmio, SEQDATA); + cyber_out8(cyber_mmio, SEQINDEX, 0xDD); + savedRegDD[1] = cyber_in8(cyber_mmio, SEQDATA); + */ + + + savedReg74 = 0x1b; + savedReg74 = 0x1e; + + savedRegD9[0] = 0x0f; + savedRegDA[0] = 0x1b; + savedRegDD[0] = 0x00; + + savedRegD9[1] = 0x0f; + savedRegDA[1] = 0x1b; + savedRegDD[1] = 0x00; +} + +void cyber_change_overlay_fifo(void) +{ + cyber_grphw(0x74, bFIFOPolicyNum[0]); + cyber_grphw(0x75, bFIFOPolicyNum[1]); + cyber_grphw(0xD9, bFIFOPolicyNum[2]); + cyber_grphw(0xDA, bFIFOPolicyNum[3]); + + cyber_videoreg_mask(0xA6, 0x08, ~0x08); + cyber_videoreg_mask(0xF1, 0x40, (unsigned char)(~0xC0)); + cyber_overlayreg_mask(FIFO_CTL_I, bFIFOPolicyNum[4] & 0x05, ~0x05); + cyber_overlayreg_mask(FIFO_CTL_I, 0x2, ~0x02); +} + +void cyber_set_overlay_format(int format) { + switch (format) { + case OVERLAY_YUV422: + cyber_overlayreg_mask( VIDEO_FORMAT, 0x00, 0xF8 ); + overlay_byte_per_pixel = 2; + break; + case OVERLAY_RGB555: + cyber_overlayreg_mask( VIDEO_FORMAT, 0x01, 0xF8 ); + overlay_byte_per_pixel = 2; + break; + case OVERLAY_RGB565: + cyber_overlayreg_mask( VIDEO_FORMAT, 0x02, 0xF8 ); + overlay_byte_per_pixel = 2; + break; + case OVERLAY_RGB888: + cyber_overlayreg_mask( VIDEO_FORMAT, 0x03, 0xF8 ); + overlay_byte_per_pixel = 3; + break; + case OVERLAY_RGB8888: + cyber_overlayreg_mask( VIDEO_FORMAT, 0x04, 0xF8 ); + overlay_byte_per_pixel = 4; + break; + case OVERLAY_RGB8: + cyber_overlayreg_mask( VIDEO_FORMAT, 0x05, 0xF8 ); + overlay_byte_per_pixel = 1; + break; + case OVERLAY_RGB4444: + cyber_overlayreg_mask( VIDEO_FORMAT, 0x06, 0xF8 ); + overlay_byte_per_pixel = 2; + break; + case OVERLAY_RGB8T: + cyber_overlayreg_mask( VIDEO_FORMAT, 0x07, 0xF8 ); + overlay_byte_per_pixel = 1; + break; + } +} + +void cyber_set_overlay_mode(int mode) +{ + switch (mode) { + case OVERLAY_COLORKEY: + cyber_overlayreg_mask( DISP_CTL_I, 0x00, 0xFD ); + break; + case OVERLAY_WINDOWKEY: + default: + cyber_overlayreg_mask( DISP_CTL_I, 0x02, 0xFD ); + break; + } +} + +void cyber_set_overlay_srcaddr(int addr, int x, int y, int width, int pitch) +{ + unsigned char bHigh; + int wByteFetch; + + addr += y * pitch + x * overlay_byte_per_pixel; + addr >>= 2; + + /*playback start addr*/ + cyber_grphw( MEMORY_START_L, (unsigned char)( addr & 0x0000FF) ); + cyber_grphw( MEMORY_START_M, (unsigned char)((addr & 0x00FF00) >> 8) ); + cyber_grphw( MEMORY_START_H, (unsigned char)((addr & 0xFF0000) >> 16) ); + + /* pitch is a multiple of 64 bits*/ + pitch >>= 3; /* 64 bit address field*/ + wByteFetch = (width * overlay_byte_per_pixel + 7) >> 3; + + bHigh = (unsigned char)(pitch >> 8) & 0x0F; + bHigh = bHigh | (((unsigned char)(wByteFetch >> 8)) << 4 ); + + cyber_grphw( MEMORY_PITCH_L, (unsigned char)(pitch) ); + cyber_grphw( MEMORY_PITCH_H, bHigh ); + + cyber_grphw( MEMORY_OFFSET_PHASE, (unsigned char)(wByteFetch) ); + + if (width > 720) /*Turn off interpolation*/ + cyber_overlayreg_mask( DISP_CTL_I, 0x20, 0xDF ); + else { /*Turn off interpolation*/ + if (width > 360) { /* Y Only*/ + cyber_seqreg_mask(0xA6, 0x40, ~0x40); + } + else { + cyber_seqreg_mask(0xA6, 0x00, ~0x40); + } + + cyber_overlayreg_mask( DISP_CTL_I, 0x00, 0xDF ); + } +} + +void cyber_set_overlay_window(int left, int top, int right, int bottom) +{ + cyber_grphw( DEST_RECT_LEFT_L, (unsigned char)(left ) ); + cyber_grphw( DEST_RECT_LEFT_H, (unsigned char)(left >> 8) ); + cyber_grphw( DEST_RECT_RIGHT_L, (unsigned char)(right ) ); + cyber_grphw( DEST_RECT_RIGHT_H, (unsigned char)(right >> 8) ); + + cyber_grphw( DEST_RECT_TOP_L, (unsigned char)(top ) ); + cyber_grphw( DEST_RECT_TOP_H, (unsigned char)(top >> 8) ); + cyber_grphw( DEST_RECT_BOTTOM_L, (unsigned char)(bottom ) ); + cyber_grphw( DEST_RECT_BOTTOM_H, (unsigned char)(bottom >> 8) ); +} + +void cyber_set_overlay_scale( unsigned char bEnableBob, int wSrcXExt, int wDstXExt, int wSrcYExt, int wDstYExt ) +{ + int dwScale; + + cyber_grphw( DDA_X_INIT_L, 0x0 ); /* set to 0x800;*/ + cyber_grphw( DDA_X_INIT_H, 0x8 ); + if ( wSrcXExt == wDstXExt ) + dwScale = 0x1000; + else + dwScale = ( wSrcXExt * 0x1000 ) / wDstXExt; + cyber_grphw( DDA_X_INC_L, (unsigned char)( dwScale & 0x00FF) ); + cyber_grphw( DDA_X_INC_H, (unsigned char)((dwScale & 0xFF00) >> 8) ); + + cyber_grphw( DDA_Y_INIT_L, 0x0 ); /* set to 0x800;*/ + cyber_grphw( DDA_Y_INIT_H, 0x8 ); + + if ( wSrcYExt == wDstYExt ) + dwScale = 0x1000; + else + dwScale = ( wSrcYExt * 0x1000 ) / wDstYExt; + + + if (bEnableBob == 0) {/*Disable Bob mode*/ + cyber_seqreg_mask(0xA7, 0x0, ~0x5); /*Bob/Weave disable*/ + } + else {/*Enable Bob mode*/ + wSrcYExt = wSrcYExt / 2; + if (wSrcYExt == wDstYExt) + dwScale = 0x1000; + else + dwScale = ( wSrcYExt * 0x1000 ) / wDstYExt; + if (dwScale <= 0x815 && dwScale >= 0x7eb) { + cyber_seqreg_mask(0xA7, 0x5, ~0x5); /*Bob/Weave enable*/ + } + else { + cyber_seqreg_mask(0xA7, 0x4, ~0x5); /*Bob/Weave enable*/ + } + } + + cyber_grphw( DDA_Y_INC_L, (unsigned char)( dwScale & 0x00FF) ); + cyber_grphw( DDA_Y_INC_H, (unsigned char)((dwScale & 0xFF00) >> 8) ); +} + +void cyber_enable_overlay(int enable) +{ + if (enable) + cyber_overlayreg_mask( DISP_CTL_I, 0x84, (unsigned char)(~0x84) ); + else + cyber_overlayreg_mask( DISP_CTL_I, 0x00, 0x7F ); /* Disable Vafc !!!*/ +} |