filename | src/pvr2/pvr2mem.c |
changeset | 285:4fefedafebc6 |
prev | 284:808617ee7135 |
next | 309:e2750808d02c |
author | nkeynes |
date | Wed Jan 17 21:27:20 2007 +0000 (17 years ago) |
permissions | -rw-r--r-- |
last change | Rename SPUDMA to G2DMA (following KOS's lead) Remove sh4r.icount (obsolete) Rewrite G2 fifo status in terms of slice cycles |
view | annotate | diff | log | raw |
1 /**
2 * $Id: pvr2mem.c,v 1.2 2007-01-15 10:10:51 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 }
.