Search
lxdream.org :: lxdream/src/pvr2/pvr2mem.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/pvr2/pvr2mem.c
changeset 284:808617ee7135
next285:4fefedafebc6
author nkeynes
date Mon Jan 15 08:32:09 2007 +0000 (13 years ago)
permissions -rw-r--r--
last change Break vram routines out into pvr2mem.c
Initial (untested) implementation of stride textures
Hookup YUV converter code in pvr2.c
view annotate diff log raw
     1 /**
     2  * $Id: pvr2mem.c,v 1.1 2007-01-15 08:32:09 nkeynes Exp $
     3  *
     4  * PVR2 (Video) VRAM handling routines (mainly for the 64-bit region)
     5  *
     6  * Copyright (c) 2005 Nathan Keynes.
     7  *
     8  * This program is free software; you can redistribute it and/or modify
     9  * it under the terms of the GNU General Public License as published by
    10  * the Free Software Foundation; either version 2 of the License, or
    11  * (at your option) any later version.
    12  *
    13  * This program is distributed in the hope that it will be useful,
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16  * GNU General Public License for more details.
    17  */
    18 #include "pvr2.h"
    20 extern char *video_base;
    22 void pvr2_vram64_write( sh4addr_t destaddr, char *src, uint32_t length )
    23 {
    24     int bank_flag = (destaddr & 0x04) >> 2;
    25     uint32_t *banks[2];
    26     uint32_t *dwsrc;
    27     int i;
    29     destaddr = destaddr & 0x7FFFFF;
    30     if( destaddr + length > 0x800000 ) {
    31 	length = 0x800000 - destaddr;
    32     }
    34     for( i=destaddr & 0xFFFFF000; i < destaddr + length; i+= PAGE_SIZE ) {
    35 	texcache_invalidate_page( i );
    36     }
    38     banks[0] = ((uint32_t *)(video_base + ((destaddr & 0x007FFFF8) >>1)));
    39     banks[1] = banks[0] + 0x100000;
    40     if( bank_flag ) 
    41 	banks[0]++;
    43     /* Handle non-aligned start of source */
    44     if( destaddr & 0x03 ) {
    45 	char *dest = ((char *)banks[bank_flag]) + (destaddr & 0x03);
    46 	for( i= destaddr & 0x03; i < 4 && length > 0; i++, length-- ) {
    47 	    *dest++ = *src++;
    48 	}
    49 	bank_flag = !bank_flag;
    50     }
    52     dwsrc = (uint32_t *)src;
    53     while( length >= 4 ) {
    54 	*banks[bank_flag]++ = *dwsrc++;
    55 	bank_flag = !bank_flag;
    56 	length -= 4;
    57     }
    59     /* Handle non-aligned end of source */
    60     if( length ) {
    61 	src = (char *)dwsrc;
    62 	char *dest = (char *)banks[bank_flag];
    63 	while( length-- > 0 ) {
    64 	    *dest++ = *src++;
    65 	}
    66     }  
    67 }
    69 /**
    70  * Write an image to 64-bit vram, with a line-stride different from the line-size.
    71  * The destaddr must be 32-bit aligned, and both line_bytes and line_stride_bytes
    72  * must be multiples of 4.
    73  */
    74 void pvr2_vram64_write_stride( sh4addr_t destaddr, char *src, uint32_t line_bytes, 
    75 			       uint32_t line_stride_bytes, uint32_t line_count )
    76 {
    77     int bank_flag = (destaddr & 0x04) >> 2;
    78     uint32_t *banks[2];
    79     uint32_t *dwsrc;
    80     uint32_t line_gap;
    81     int line_gap_flag;
    82     int i,j;
    84     destaddr = destaddr & 0x7FFFF8;
    85     i = line_stride_bytes - line_bytes;
    86     line_gap_flag = i & 0x04;
    87     line_gap = i >> 3;
    88     line_bytes >>= 2;
    90     for( i=destaddr & 0xFFFFF000; i < destaddr + line_stride_bytes*line_count; i+= PAGE_SIZE ) {
    91 	texcache_invalidate_page( i );
    92     }
    94     banks[0] = (uint32_t *)(video_base + (destaddr >>1));
    95     banks[1] = banks[0] + 0x100000;
    96     if( bank_flag ) 
    97 	banks[0]++;
    99     dwsrc = (uint32_t *)src;
   100     for( i=0; i<line_count; i++ ) {
   101 	for( j=0; j<line_bytes; j++ ) {
   102 	    *banks[bank_flag]++ = *dwsrc++;
   103 	    bank_flag = !bank_flag;
   104 	}
   105 	*banks[0] += line_gap;
   106 	*banks[1] += line_gap;
   107 	if( line_gap_flag ) {
   108 	    *banks[bank_flag]++;
   109 	    bank_flag = !bank_flag;
   110 	}
   111     }    
   112 }
   114 /**
   115  * Read an image from 64-bit vram, with a destination line-stride different from the line-size.
   116  * The srcaddr must be 32-bit aligned, and both line_bytes and line_stride_bytes
   117  * must be multiples of 4. line_stride_bytes must be >= line_bytes.
   118  * This method is used to extract a "stride" texture from vram.
   119  */
   120 void pvr2_vram64_read_stride( char *dest, uint32_t dest_line_bytes, sh4addr_t srcaddr,
   121 				   uint32_t src_line_bytes, uint32_t line_count )
   122 {
   123     int bank_flag = (srcaddr & 0x04) >> 2;
   124     uint32_t *banks[2];
   125     uint32_t *dwdest;
   126     uint32_t dest_line_gap;
   127     uint32_t src_line_gap;
   128     uint32_t line_bytes;
   129     int src_line_gap_flag;
   130     int i,j;
   132     srcaddr = srcaddr & 0x7FFFF8;
   133     if( src_line_bytes <= dest_line_bytes ) {
   134 	dest_line_gap = (dest_line_bytes - src_line_bytes) >> 2;
   135 	src_line_gap = 0;
   136 	src_line_gap_flag = 0;
   137 	line_bytes = src_line_bytes >> 2;
   138     } else {
   139 	i = (src_line_bytes - dest_line_bytes);
   140 	src_line_gap_flag = i & 0x04;
   141 	src_line_gap = i >> 3;
   142 	line_bytes = dest_line_bytes >> 2;
   143     }
   145     banks[0] = (uint32_t *)(video_base + (srcaddr>>1));
   146     banks[1] = banks[0] + 0x100000;
   147     if( bank_flag )
   148 	banks[0]++;
   150     dwdest = (uint32_t *)dest;
   151     for( i=0; i<line_count; i++ ) {
   152 	for( j=0; j<line_bytes; j++ ) {
   153 	    *dwdest++ = *banks[bank_flag]++;
   154 	    bank_flag = !bank_flag;
   155 	}
   156 	dwdest += dest_line_gap;
   157 	banks[0] += src_line_gap;
   158 	banks[1] += src_line_gap;
   159 	if( src_line_gap_flag ) {
   160 	    banks[bank_flag]++;
   161 	    bank_flag = !bank_flag;
   162 	}
   163     }
   165 }
   167 void pvr2_vram_write_invert( sh4addr_t destaddr, char *src, uint32_t length, uint32_t line_length )
   168 {
   169     char *dest = video_base + (destaddr & 0x007FFFFF);
   170     char *p = src + length - line_length;
   171     while( p >= src ) {
   172 	memcpy( dest, p, line_length );
   173 	p -= line_length;
   174 	dest += line_length;
   175     }
   176 }
   178 void pvr2_vram64_read( char *dest, sh4addr_t srcaddr, uint32_t length )
   179 {
   180     int bank_flag = (srcaddr & 0x04) >> 2;
   181     uint32_t *banks[2];
   182     uint32_t *dwdest;
   183     int i;
   185     srcaddr = srcaddr & 0x7FFFFF;
   186     if( srcaddr + length > 0x800000 )
   187 	length = 0x800000 - srcaddr;
   189     banks[0] = ((uint32_t *)(video_base + ((srcaddr&0x007FFFF8)>>1)));
   190     banks[1] = banks[0] + 0x100000;
   191     if( bank_flag )
   192 	banks[0]++;
   194     /* Handle non-aligned start of source */
   195     if( srcaddr & 0x03 ) {
   196 	char *src = ((char *)banks[bank_flag]) + (srcaddr & 0x03);
   197 	for( i= srcaddr & 0x03; i < 4 && length > 0; i++, length-- ) {
   198 	    *dest++ = *src++;
   199 	}
   200 	bank_flag = !bank_flag;
   201     }
   203     dwdest = (uint32_t *)dest;
   204     while( length >= 4 ) {
   205 	*dwdest++ = *banks[bank_flag]++;
   206 	bank_flag = !bank_flag;
   207 	length -= 4;
   208     }
   210     /* Handle non-aligned end of source */
   211     if( length ) {
   212 	dest = (char *)dwdest;
   213 	char *src = (char *)banks[bank_flag];
   214 	while( length-- > 0 ) {
   215 	    *dest++ = *src++;
   216 	}
   217     }
   218 }
   220 void pvr2_vram64_dump( sh4addr_t addr, uint32_t length, FILE *f ) 
   221 {
   222     char tmp[length];
   223     pvr2_vram64_read( tmp, addr, length );
   224     fwrite_dump( tmp, length, f );
   225 }
.