Search
lxdream.org :: lxdream/src/pvr2/pvr2mem.c :: diff
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 (12 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
file annotate diff log raw
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/pvr2/pvr2mem.c Mon Jan 15 08:32:09 2007 +0000
1.3 @@ -0,0 +1,225 @@
1.4 +/**
1.5 + * $Id: pvr2mem.c,v 1.1 2007-01-15 08:32:09 nkeynes Exp $
1.6 + *
1.7 + * PVR2 (Video) VRAM handling routines (mainly for the 64-bit region)
1.8 + *
1.9 + * Copyright (c) 2005 Nathan Keynes.
1.10 + *
1.11 + * This program is free software; you can redistribute it and/or modify
1.12 + * it under the terms of the GNU General Public License as published by
1.13 + * the Free Software Foundation; either version 2 of the License, or
1.14 + * (at your option) any later version.
1.15 + *
1.16 + * This program is distributed in the hope that it will be useful,
1.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.19 + * GNU General Public License for more details.
1.20 + */
1.21 +#include "pvr2.h"
1.22 +
1.23 +extern char *video_base;
1.24 +
1.25 +void pvr2_vram64_write( sh4addr_t destaddr, char *src, uint32_t length )
1.26 +{
1.27 + int bank_flag = (destaddr & 0x04) >> 2;
1.28 + uint32_t *banks[2];
1.29 + uint32_t *dwsrc;
1.30 + int i;
1.31 +
1.32 + destaddr = destaddr & 0x7FFFFF;
1.33 + if( destaddr + length > 0x800000 ) {
1.34 + length = 0x800000 - destaddr;
1.35 + }
1.36 +
1.37 + for( i=destaddr & 0xFFFFF000; i < destaddr + length; i+= PAGE_SIZE ) {
1.38 + texcache_invalidate_page( i );
1.39 + }
1.40 +
1.41 + banks[0] = ((uint32_t *)(video_base + ((destaddr & 0x007FFFF8) >>1)));
1.42 + banks[1] = banks[0] + 0x100000;
1.43 + if( bank_flag )
1.44 + banks[0]++;
1.45 +
1.46 + /* Handle non-aligned start of source */
1.47 + if( destaddr & 0x03 ) {
1.48 + char *dest = ((char *)banks[bank_flag]) + (destaddr & 0x03);
1.49 + for( i= destaddr & 0x03; i < 4 && length > 0; i++, length-- ) {
1.50 + *dest++ = *src++;
1.51 + }
1.52 + bank_flag = !bank_flag;
1.53 + }
1.54 +
1.55 + dwsrc = (uint32_t *)src;
1.56 + while( length >= 4 ) {
1.57 + *banks[bank_flag]++ = *dwsrc++;
1.58 + bank_flag = !bank_flag;
1.59 + length -= 4;
1.60 + }
1.61 +
1.62 + /* Handle non-aligned end of source */
1.63 + if( length ) {
1.64 + src = (char *)dwsrc;
1.65 + char *dest = (char *)banks[bank_flag];
1.66 + while( length-- > 0 ) {
1.67 + *dest++ = *src++;
1.68 + }
1.69 + }
1.70 +}
1.71 +
1.72 +/**
1.73 + * Write an image to 64-bit vram, with a line-stride different from the line-size.
1.74 + * The destaddr must be 32-bit aligned, and both line_bytes and line_stride_bytes
1.75 + * must be multiples of 4.
1.76 + */
1.77 +void pvr2_vram64_write_stride( sh4addr_t destaddr, char *src, uint32_t line_bytes,
1.78 + uint32_t line_stride_bytes, uint32_t line_count )
1.79 +{
1.80 + int bank_flag = (destaddr & 0x04) >> 2;
1.81 + uint32_t *banks[2];
1.82 + uint32_t *dwsrc;
1.83 + uint32_t line_gap;
1.84 + int line_gap_flag;
1.85 + int i,j;
1.86 +
1.87 + destaddr = destaddr & 0x7FFFF8;
1.88 + i = line_stride_bytes - line_bytes;
1.89 + line_gap_flag = i & 0x04;
1.90 + line_gap = i >> 3;
1.91 + line_bytes >>= 2;
1.92 +
1.93 + for( i=destaddr & 0xFFFFF000; i < destaddr + line_stride_bytes*line_count; i+= PAGE_SIZE ) {
1.94 + texcache_invalidate_page( i );
1.95 + }
1.96 +
1.97 + banks[0] = (uint32_t *)(video_base + (destaddr >>1));
1.98 + banks[1] = banks[0] + 0x100000;
1.99 + if( bank_flag )
1.100 + banks[0]++;
1.101 +
1.102 + dwsrc = (uint32_t *)src;
1.103 + for( i=0; i<line_count; i++ ) {
1.104 + for( j=0; j<line_bytes; j++ ) {
1.105 + *banks[bank_flag]++ = *dwsrc++;
1.106 + bank_flag = !bank_flag;
1.107 + }
1.108 + *banks[0] += line_gap;
1.109 + *banks[1] += line_gap;
1.110 + if( line_gap_flag ) {
1.111 + *banks[bank_flag]++;
1.112 + bank_flag = !bank_flag;
1.113 + }
1.114 + }
1.115 +}
1.116 +
1.117 +/**
1.118 + * Read an image from 64-bit vram, with a destination line-stride different from the line-size.
1.119 + * The srcaddr must be 32-bit aligned, and both line_bytes and line_stride_bytes
1.120 + * must be multiples of 4. line_stride_bytes must be >= line_bytes.
1.121 + * This method is used to extract a "stride" texture from vram.
1.122 + */
1.123 +void pvr2_vram64_read_stride( char *dest, uint32_t dest_line_bytes, sh4addr_t srcaddr,
1.124 + uint32_t src_line_bytes, uint32_t line_count )
1.125 +{
1.126 + int bank_flag = (srcaddr & 0x04) >> 2;
1.127 + uint32_t *banks[2];
1.128 + uint32_t *dwdest;
1.129 + uint32_t dest_line_gap;
1.130 + uint32_t src_line_gap;
1.131 + uint32_t line_bytes;
1.132 + int src_line_gap_flag;
1.133 + int i,j;
1.134 +
1.135 + srcaddr = srcaddr & 0x7FFFF8;
1.136 + if( src_line_bytes <= dest_line_bytes ) {
1.137 + dest_line_gap = (dest_line_bytes - src_line_bytes) >> 2;
1.138 + src_line_gap = 0;
1.139 + src_line_gap_flag = 0;
1.140 + line_bytes = src_line_bytes >> 2;
1.141 + } else {
1.142 + i = (src_line_bytes - dest_line_bytes);
1.143 + src_line_gap_flag = i & 0x04;
1.144 + src_line_gap = i >> 3;
1.145 + line_bytes = dest_line_bytes >> 2;
1.146 + }
1.147 +
1.148 + banks[0] = (uint32_t *)(video_base + (srcaddr>>1));
1.149 + banks[1] = banks[0] + 0x100000;
1.150 + if( bank_flag )
1.151 + banks[0]++;
1.152 +
1.153 + dwdest = (uint32_t *)dest;
1.154 + for( i=0; i<line_count; i++ ) {
1.155 + for( j=0; j<line_bytes; j++ ) {
1.156 + *dwdest++ = *banks[bank_flag]++;
1.157 + bank_flag = !bank_flag;
1.158 + }
1.159 + dwdest += dest_line_gap;
1.160 + banks[0] += src_line_gap;
1.161 + banks[1] += src_line_gap;
1.162 + if( src_line_gap_flag ) {
1.163 + banks[bank_flag]++;
1.164 + bank_flag = !bank_flag;
1.165 + }
1.166 + }
1.167 +
1.168 +}
1.169 +
1.170 +void pvr2_vram_write_invert( sh4addr_t destaddr, char *src, uint32_t length, uint32_t line_length )
1.171 +{
1.172 + char *dest = video_base + (destaddr & 0x007FFFFF);
1.173 + char *p = src + length - line_length;
1.174 + while( p >= src ) {
1.175 + memcpy( dest, p, line_length );
1.176 + p -= line_length;
1.177 + dest += line_length;
1.178 + }
1.179 +}
1.180 +
1.181 +void pvr2_vram64_read( char *dest, sh4addr_t srcaddr, uint32_t length )
1.182 +{
1.183 + int bank_flag = (srcaddr & 0x04) >> 2;
1.184 + uint32_t *banks[2];
1.185 + uint32_t *dwdest;
1.186 + int i;
1.187 +
1.188 + srcaddr = srcaddr & 0x7FFFFF;
1.189 + if( srcaddr + length > 0x800000 )
1.190 + length = 0x800000 - srcaddr;
1.191 +
1.192 + banks[0] = ((uint32_t *)(video_base + ((srcaddr&0x007FFFF8)>>1)));
1.193 + banks[1] = banks[0] + 0x100000;
1.194 + if( bank_flag )
1.195 + banks[0]++;
1.196 +
1.197 + /* Handle non-aligned start of source */
1.198 + if( srcaddr & 0x03 ) {
1.199 + char *src = ((char *)banks[bank_flag]) + (srcaddr & 0x03);
1.200 + for( i= srcaddr & 0x03; i < 4 && length > 0; i++, length-- ) {
1.201 + *dest++ = *src++;
1.202 + }
1.203 + bank_flag = !bank_flag;
1.204 + }
1.205 +
1.206 + dwdest = (uint32_t *)dest;
1.207 + while( length >= 4 ) {
1.208 + *dwdest++ = *banks[bank_flag]++;
1.209 + bank_flag = !bank_flag;
1.210 + length -= 4;
1.211 + }
1.212 +
1.213 + /* Handle non-aligned end of source */
1.214 + if( length ) {
1.215 + dest = (char *)dwdest;
1.216 + char *src = (char *)banks[bank_flag];
1.217 + while( length-- > 0 ) {
1.218 + *dest++ = *src++;
1.219 + }
1.220 + }
1.221 +}
1.222 +
1.223 +void pvr2_vram64_dump( sh4addr_t addr, uint32_t length, FILE *f )
1.224 +{
1.225 + char tmp[length];
1.226 + pvr2_vram64_read( tmp, addr, length );
1.227 + fwrite_dump( tmp, length, f );
1.228 +}
.