4 * PVR2 (Video) VRAM handling routines (mainly for the 64-bit region)
6 * Copyright (c) 2005 Nathan Keynes.
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.
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.
21 #include "sh4/sh4core.h"
26 unsigned char pvr2_main_ram[8 MB];
28 /************************* VRAM32 address space ***************************/
30 static int32_t FASTCALL pvr2_vram32_read_long( sh4addr_t addr )
32 pvr2_render_buffer_invalidate(addr, FALSE);
33 return *((int32_t *)(pvr2_main_ram+(addr&0x007FFFFF)));
35 static int32_t FASTCALL pvr2_vram32_read_word( sh4addr_t addr )
37 pvr2_render_buffer_invalidate(addr, FALSE);
38 return SIGNEXT16(*((int16_t *)(pvr2_main_ram+(addr&0x007FFFFF))));
40 static int32_t FASTCALL pvr2_vram32_read_byte( sh4addr_t addr )
42 pvr2_render_buffer_invalidate(addr, FALSE);
43 return SIGNEXT8(*((int8_t *)(pvr2_main_ram+(addr&0x007FFFFF))));
45 static void FASTCALL pvr2_vram32_write_long( sh4addr_t addr, uint32_t val )
47 pvr2_render_buffer_invalidate(addr, TRUE);
48 *(uint32_t *)(pvr2_main_ram + (addr&0x007FFFFF)) = val;
50 static void FASTCALL pvr2_vram32_write_word( sh4addr_t addr, uint32_t val )
52 pvr2_render_buffer_invalidate(addr, TRUE);
53 *(uint16_t *)(pvr2_main_ram + (addr&0x007FFFFF)) = (uint16_t)val;
55 static void FASTCALL pvr2_vram32_write_byte( sh4addr_t addr, uint32_t val )
57 pvr2_render_buffer_invalidate(addr, TRUE);
58 *(uint8_t *)(pvr2_main_ram + (addr&0x007FFFFF)) = (uint8_t)val;
60 static void FASTCALL pvr2_vram32_read_burst( unsigned char *dest, sh4addr_t addr )
62 // Render buffers pretty much have to be (at least) 32-byte aligned
63 pvr2_render_buffer_invalidate(addr, FALSE);
64 memcpy( dest, (pvr2_main_ram + (addr&0x007FFFFF)), 32 );
66 static void FASTCALL pvr2_vram32_write_burst( sh4addr_t addr, unsigned char *src )
68 // Render buffers pretty much have to be (at least) 32-byte aligned
69 pvr2_render_buffer_invalidate(addr, TRUE);
70 memcpy( (pvr2_main_ram + (addr&0x007FFFFF)), src, 32 );
73 struct mem_region_fn mem_region_vram32 = { pvr2_vram32_read_long, pvr2_vram32_write_long,
74 pvr2_vram32_read_word, pvr2_vram32_write_word,
75 pvr2_vram32_read_byte, pvr2_vram32_write_byte,
76 pvr2_vram32_read_burst, pvr2_vram32_write_burst };
78 /************************* VRAM64 address space ***************************/
80 #define TRANSLATE_VIDEO_64BIT_ADDRESS(a) ( (((a)&0x00FFFFF8)>>1)|(((a)&0x00000004)<<20)|((a)&0x03) )
82 static int32_t FASTCALL pvr2_vram64_read_long( sh4addr_t addr )
84 addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);
85 pvr2_render_buffer_invalidate(addr, FALSE);
86 return *((int32_t *)(pvr2_main_ram+(addr&0x007FFFFF)));
88 static int32_t FASTCALL pvr2_vram64_read_word( sh4addr_t addr )
90 addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);
91 pvr2_render_buffer_invalidate(addr, FALSE);
92 return SIGNEXT16(*((int16_t *)(pvr2_main_ram+(addr&0x007FFFFF))));
94 static int32_t FASTCALL pvr2_vram64_read_byte( sh4addr_t addr )
96 addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);
97 pvr2_render_buffer_invalidate(addr, FALSE);
98 return SIGNEXT8(*((int8_t *)(pvr2_main_ram+(addr&0x007FFFFF))));
100 static void FASTCALL pvr2_vram64_write_long( sh4addr_t addr, uint32_t val )
102 texcache_invalidate_page(addr& 0x007FFFFF);
103 addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);
104 pvr2_render_buffer_invalidate(addr, TRUE);
105 *(uint32_t *)(pvr2_main_ram + (addr&0x007FFFFF)) = val;
107 static void FASTCALL pvr2_vram64_write_word( sh4addr_t addr, uint32_t val )
109 texcache_invalidate_page(addr& 0x007FFFFF);
110 addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);
111 pvr2_render_buffer_invalidate(addr, TRUE);
112 *(uint16_t *)(pvr2_main_ram + (addr&0x007FFFFF)) = (uint16_t)val;
114 static void FASTCALL pvr2_vram64_write_byte( sh4addr_t addr, uint32_t val )
116 texcache_invalidate_page(addr& 0x007FFFFF);
117 addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);
118 pvr2_render_buffer_invalidate(addr, TRUE);
119 *(uint8_t *)(pvr2_main_ram + (addr&0x007FFFFF)) = (uint8_t)val;
121 static void FASTCALL pvr2_vram64_read_burst( unsigned char *dest, sh4addr_t addr )
123 pvr2_vram64_read( dest, addr, 32 );
125 static void FASTCALL pvr2_vram64_write_burst( sh4addr_t addr, unsigned char *src )
127 pvr2_vram64_write( addr, src, 32 );
130 struct mem_region_fn mem_region_vram64 = { pvr2_vram64_read_long, pvr2_vram64_write_long,
131 pvr2_vram64_read_word, pvr2_vram64_write_word,
132 pvr2_vram64_read_byte, pvr2_vram64_write_byte,
133 pvr2_vram64_read_burst, pvr2_vram64_write_burst };
135 /******************************* Burst areas ******************************/
137 static void FASTCALL pvr2_vramdma1_write_burst( sh4addr_t destaddr, unsigned char *src )
139 int region = MMIO_READ( ASIC, PVRDMARGN1 );
141 pvr2_vram64_write( destaddr, src, 32 );
143 destaddr &= PVR2_RAM_MASK;
144 unsigned char *dest = pvr2_main_ram + destaddr;
145 memcpy( dest, src, 32 );
149 static void FASTCALL pvr2_vramdma2_write_burst( sh4addr_t destaddr, unsigned char *src )
151 int region = MMIO_READ( ASIC, PVRDMARGN2 );
153 pvr2_vram64_write( destaddr, src, 32 );
155 destaddr &= PVR2_RAM_MASK;
156 unsigned char *dest = pvr2_main_ram + destaddr;
157 memcpy( dest, src, 32 );
161 static void FASTCALL pvr2_yuv_write_burst( sh4addr_t destaddr, unsigned char *src )
163 pvr2_yuv_write( src, 32 );
166 struct mem_region_fn mem_region_pvr2ta = {
167 unmapped_read_long, unmapped_write_long,
168 unmapped_read_long, unmapped_write_long,
169 unmapped_read_long, unmapped_write_long,
170 unmapped_read_burst, pvr2_ta_write_burst };
172 struct mem_region_fn mem_region_pvr2yuv = {
173 unmapped_read_long, unmapped_write_long,
174 unmapped_read_long, unmapped_write_long,
175 unmapped_read_long, unmapped_write_long,
176 unmapped_read_burst, pvr2_yuv_write_burst };
178 struct mem_region_fn mem_region_pvr2vdma1 = {
179 unmapped_read_long, unmapped_write_long,
180 unmapped_read_long, unmapped_write_long,
181 unmapped_read_long, unmapped_write_long,
182 unmapped_read_burst, pvr2_vramdma1_write_burst };
184 struct mem_region_fn mem_region_pvr2vdma2 = {
185 unmapped_read_long, unmapped_write_long,
186 unmapped_read_long, unmapped_write_long,
187 unmapped_read_long, unmapped_write_long,
188 unmapped_read_burst, pvr2_vramdma2_write_burst };
191 void pvr2_dma_write( sh4addr_t destaddr, unsigned char *src, uint32_t count )
195 switch( destaddr & 0x13800000 ) {
198 pvr2_ta_write( src, count );
202 region = MMIO_READ( ASIC, PVRDMARGN1 );
204 pvr2_vram64_write( destaddr, src, count );
206 destaddr &= PVR2_RAM_MASK;
207 unsigned char *dest = pvr2_main_ram + destaddr;
208 if( PVR2_RAM_SIZE - destaddr < count ) {
209 count = PVR2_RAM_SIZE - destaddr;
211 memcpy( dest, src, count );
216 pvr2_yuv_write( src, count );
220 region = MMIO_READ( ASIC, PVRDMARGN2 );
222 pvr2_vram64_write( destaddr, src, count );
224 destaddr &= PVR2_RAM_MASK;
225 unsigned char *dest = pvr2_main_ram + destaddr;
226 if( PVR2_RAM_SIZE - destaddr < count ) {
227 count = PVR2_RAM_SIZE - destaddr;
229 memcpy( dest, src, count );
234 void pvr2_vram64_write( sh4addr_t destaddr, unsigned char *src, uint32_t length )
236 int bank_flag = (destaddr & 0x04) >> 2;
241 destaddr = destaddr & 0x7FFFFF;
242 if( destaddr + length > 0x800000 ) {
243 length = 0x800000 - destaddr;
246 for( i=destaddr & 0xFFFFF000; i < destaddr + length; i+= LXDREAM_PAGE_SIZE ) {
247 texcache_invalidate_page( i );
250 banks[0] = ((uint32_t *)(pvr2_main_ram + ((destaddr & 0x007FFFF8) >>1)));
251 banks[1] = banks[0] + 0x100000;
255 /* Handle non-aligned start of source */
256 if( destaddr & 0x03 ) {
257 unsigned char *dest = ((unsigned char *)banks[bank_flag]) + (destaddr & 0x03);
258 for( i= destaddr & 0x03; i < 4 && length > 0; i++, length-- ) {
261 bank_flag = !bank_flag;
264 dwsrc = (uint32_t *)src;
265 while( length >= 4 ) {
266 *banks[bank_flag]++ = *dwsrc++;
267 bank_flag = !bank_flag;
271 /* Handle non-aligned end of source */
273 src = (unsigned char *)dwsrc;
274 unsigned char *dest = (unsigned char *)banks[bank_flag];
275 while( length-- > 0 ) {
282 * Write an image to 64-bit vram, with a line-stride different from the line-size.
283 * The destaddr must be 64-bit aligned, and both line_bytes and line_stride_bytes
284 * must be multiples of 8.
286 void pvr2_vram64_write_stride( sh4addr_t destaddr, unsigned char *src, uint32_t line_bytes,
287 uint32_t line_stride_bytes, uint32_t line_count )
291 uint32_t *dwsrc = (uint32_t *)src;
292 uint32_t line_gap = (line_stride_bytes - line_bytes) >> 3;
294 destaddr = destaddr & 0x7FFFF8;
297 for( i=destaddr; i < destaddr + line_stride_bytes*line_count; i+= LXDREAM_PAGE_SIZE ) {
298 texcache_invalidate_page( i );
301 banks[0] = (uint32_t *)(pvr2_main_ram + (destaddr >>1));
302 banks[1] = banks[0] + 0x100000;
304 for( i=0; i<line_count; i++ ) {
305 for( j=0; j<line_bytes; j++ ) {
306 *banks[0]++ = *dwsrc++;
307 *banks[1]++ = *dwsrc++;
309 banks[0] += line_gap;
310 banks[1] += line_gap;
315 * Read an image from 64-bit vram, with a destination line-stride different from the line-size.
316 * The srcaddr must be 32-bit aligned, and both line_bytes and line_stride_bytes
317 * must be multiples of 4. line_stride_bytes must be >= line_bytes.
318 * This method is used to extract a "stride" texture from vram.
320 void pvr2_vram64_read_stride( unsigned char *dest, uint32_t dest_line_bytes, sh4addr_t srcaddr,
321 uint32_t src_line_bytes, uint32_t line_count )
323 int bank_flag = (srcaddr & 0x04) >> 2;
326 uint32_t dest_line_gap = 0;
327 uint32_t src_line_gap = 0;
329 int src_line_gap_flag;
332 srcaddr = srcaddr & 0x7FFFF8;
333 if( src_line_bytes <= dest_line_bytes ) {
334 dest_line_gap = (dest_line_bytes - src_line_bytes) >> 2;
336 src_line_gap_flag = 0;
337 line_bytes = src_line_bytes >> 2;
339 i = (src_line_bytes - dest_line_bytes);
340 src_line_gap_flag = i & 0x04;
341 src_line_gap = i >> 3;
342 line_bytes = dest_line_bytes >> 2;
345 banks[0] = (uint32_t *)(pvr2_main_ram + (srcaddr>>1));
346 banks[1] = banks[0] + 0x100000;
350 dwdest = (uint32_t *)dest;
351 for( i=0; i<line_count; i++ ) {
352 for( j=0; j<line_bytes; j++ ) {
353 *dwdest++ = *banks[bank_flag]++;
354 bank_flag = !bank_flag;
356 dwdest += dest_line_gap;
357 banks[0] += src_line_gap;
358 banks[1] += src_line_gap;
359 if( src_line_gap_flag ) {
361 bank_flag = !bank_flag;
368 * @param dest Destination image buffer
369 * @param banks Source data expressed as two bank pointers
370 * @param offset Offset into banks[0] specifying where the next byte
372 * @param x1,y1 Destination coordinates
373 * @param width Width of current destination block
374 * @param stride Total width of image (ie stride) in bytes
377 static void pvr2_vram64_detwiddle_4( uint8_t *dest, uint8_t *banks[2], int offset,
378 int x1, int y1, int width, int stride )
382 uint8_t t1 = *banks[offset<4?0:1]++;
383 uint8_t t2 = *banks[offset<3?0:1]++;
384 dest[y1*stride + x1] = (t1 & 0x0F) | (t2<<4);
385 dest[(y1+1)*stride + x1] = (t1>>4) | (t2&0xF0);
386 } else if( width == 4 ) {
387 pvr2_vram64_detwiddle_4( dest, banks, offset, x1, y1, 2, stride );
388 pvr2_vram64_detwiddle_4( dest, banks, offset+2, x1, y1+2, 2, stride );
389 pvr2_vram64_detwiddle_4( dest, banks, offset+4, x1+2, y1, 2, stride );
390 pvr2_vram64_detwiddle_4( dest, banks, offset+6, x1+2, y1+2, 2, stride );
393 int subdivide = width >> 1;
394 pvr2_vram64_detwiddle_4( dest, banks, offset, x1, y1, subdivide, stride );
395 pvr2_vram64_detwiddle_4( dest, banks, offset, x1, y1+subdivide, subdivide, stride );
396 pvr2_vram64_detwiddle_4( dest, banks, offset, x1+subdivide, y1, subdivide, stride );
397 pvr2_vram64_detwiddle_4( dest, banks, offset, x1+subdivide, y1+subdivide, subdivide, stride );
402 * @param dest Destination image buffer
403 * @param banks Source data expressed as two bank pointers
404 * @param offset Offset into banks[0] specifying where the next byte
406 * @param x1,y1 Destination coordinates
407 * @param width Width of current destination block
408 * @param stride Total width of image (ie stride)
411 static void pvr2_vram64_detwiddle_8( uint8_t *dest, uint8_t *banks[2], int offset,
412 int x1, int y1, int width, int stride )
415 dest[y1*stride + x1] = *banks[0]++;
416 dest[(y1+1)*stride + x1] = *banks[offset<3?0:1]++;
417 dest[y1*stride + x1 + 1] = *banks[offset<2?0:1]++;
418 dest[(y1+1)*stride + x1 + 1] = *banks[offset==0?0:1]++;
419 uint8_t *tmp = banks[0]; /* swap banks */
423 int subdivide = width >> 1;
424 pvr2_vram64_detwiddle_8( dest, banks, offset, x1, y1, subdivide, stride );
425 pvr2_vram64_detwiddle_8( dest, banks, offset, x1, y1+subdivide, subdivide, stride );
426 pvr2_vram64_detwiddle_8( dest, banks, offset, x1+subdivide, y1, subdivide, stride );
427 pvr2_vram64_detwiddle_8( dest, banks, offset, x1+subdivide, y1+subdivide, subdivide, stride );
432 * @param dest Destination image buffer
433 * @param banks Source data expressed as two bank pointers
434 * @param offset Offset into banks[0] specifying where the next word
435 * to read is (0 or 1)
436 * @param x1,y1 Destination coordinates
437 * @param width Width of current destination block
438 * @param stride Total width of image (ie stride)
441 static void pvr2_vram64_detwiddle_16( uint16_t *dest, uint16_t *banks[2], int offset,
442 int x1, int y1, int width, int stride )
445 dest[y1*stride + x1] = *banks[0]++;
446 dest[(y1+1)*stride + x1] = *banks[offset]++;
447 dest[y1*stride + x1 + 1] = *banks[1]++;
448 dest[(y1+1)*stride + x1 + 1] = *banks[offset^1]++;
450 int subdivide = width >> 1;
451 pvr2_vram64_detwiddle_16( dest, banks, offset, x1, y1, subdivide, stride );
452 pvr2_vram64_detwiddle_16( dest, banks, offset, x1, y1+subdivide, subdivide, stride );
453 pvr2_vram64_detwiddle_16( dest, banks, offset, x1+subdivide, y1, subdivide, stride );
454 pvr2_vram64_detwiddle_16( dest, banks, offset, x1+subdivide, y1+subdivide, subdivide, stride );
459 * Read an image from 64-bit vram stored as twiddled 4-bit pixels. The
460 * image is written out to the destination in detwiddled form.
461 * @param dest destination buffer, which must be at least width*height/2 in length
462 * @param srcaddr source address in vram
463 * @param width image width (must be a power of 2)
464 * @param height image height (must be a power of 2)
466 void pvr2_vram64_read_twiddled_4( unsigned char *dest, sh4addr_t srcaddr, uint32_t width, uint32_t height )
468 int offset_flag = (srcaddr & 0x07);
470 uint8_t *wdest = (uint8_t*)dest;
471 uint32_t stride = width >> 1;
474 srcaddr = srcaddr & 0x7FFFF8;
476 banks[0] = (uint8_t *)(pvr2_main_ram + (srcaddr>>1));
477 banks[1] = banks[0] + 0x400000;
478 if( offset_flag & 0x04 ) { // If source is not 64-bit aligned, swap the banks
479 uint8_t *tmp = banks[0];
484 banks[0] += offset_flag;
486 if( width > height ) {
487 for( i=0; i<width; i+=height ) {
488 pvr2_vram64_detwiddle_4( wdest, banks, offset_flag, i, 0, height, stride );
490 } else if( height > width ) {
491 for( i=0; i<height; i+=width ) {
492 pvr2_vram64_detwiddle_4( wdest, banks, offset_flag, 0, i, width, stride );
494 } else if( width == 1 ) {
497 pvr2_vram64_detwiddle_4( wdest, banks, offset_flag, 0, 0, width, stride );
502 * Read an image from 64-bit vram stored as twiddled 8-bit pixels. The
503 * image is written out to the destination in detwiddled form.
504 * @param dest destination buffer, which must be at least width*height in length
505 * @param srcaddr source address in vram
506 * @param width image width (must be a power of 2)
507 * @param height image height (must be a power of 2)
509 void pvr2_vram64_read_twiddled_8( unsigned char *dest, sh4addr_t srcaddr, uint32_t width, uint32_t height )
511 int offset_flag = (srcaddr & 0x07);
513 uint8_t *wdest = (uint8_t*)dest;
516 srcaddr = srcaddr & 0x7FFFF8;
518 banks[0] = (uint8_t *)(pvr2_main_ram + (srcaddr>>1));
519 banks[1] = banks[0] + 0x400000;
520 if( offset_flag & 0x04 ) { // If source is not 64-bit aligned, swap the banks
521 uint8_t *tmp = banks[0];
526 banks[0] += offset_flag;
528 if( width > height ) {
529 for( i=0; i<width; i+=height ) {
530 pvr2_vram64_detwiddle_8( wdest, banks, offset_flag, i, 0, height, width );
532 } else if( height > width ) {
533 for( i=0; i<height; i+=width ) {
534 pvr2_vram64_detwiddle_8( wdest, banks, offset_flag, 0, i, width, width );
536 } else if( width == 1 ) {
539 pvr2_vram64_detwiddle_8( wdest, banks, offset_flag, 0, 0, width, width );
544 * Read an image from 64-bit vram stored as twiddled 16-bit pixels. The
545 * image is written out to the destination in detwiddled form.
546 * @param dest destination buffer, which must be at least width*height*2 in length
547 * @param srcaddr source address in vram (must be 16-bit aligned)
548 * @param width image width (must be a power of 2)
549 * @param height image height (must be a power of 2)
551 void pvr2_vram64_read_twiddled_16( unsigned char *dest, sh4addr_t srcaddr, uint32_t width, uint32_t height ) {
552 int offset_flag = (srcaddr & 0x06) >> 1;
554 uint16_t *wdest = (uint16_t*)dest;
557 srcaddr = srcaddr & 0x7FFFF8;
559 banks[0] = (uint16_t *)(pvr2_main_ram + (srcaddr>>1));
560 banks[1] = banks[0] + 0x200000;
561 if( offset_flag & 0x02 ) { // If source is not 64-bit aligned, swap the banks
562 uint16_t *tmp = banks[0];
567 banks[0] += offset_flag;
570 if( width > height ) {
571 for( i=0; i<width; i+=height ) {
572 pvr2_vram64_detwiddle_16( wdest, banks, offset_flag, i, 0, height, width );
574 } else if( height > width ) {
575 for( i=0; i<height; i+=width ) {
576 pvr2_vram64_detwiddle_16( wdest, banks, offset_flag, 0, i, width, width );
578 } else if( width == 1 ) {
581 pvr2_vram64_detwiddle_16( wdest, banks, offset_flag, 0, 0, width, width );
585 static void pvr2_vram_write_invert( sh4addr_t destaddr, unsigned char *src, uint32_t src_size,
586 uint32_t line_size, uint32_t dest_stride,
587 uint32_t src_stride )
589 unsigned char *dest = pvr2_main_ram + (destaddr & 0x007FFFFF);
590 unsigned char *p = src + src_size - src_stride;
592 memcpy( dest, p, line_size );
598 static void pvr2_vram64_write_invert( sh4addr_t destaddr, unsigned char *src,
599 uint32_t src_size, uint32_t line_size,
600 uint32_t dest_stride, uint32_t src_stride )
604 uint32_t *dwsrc = (uint32_t *)(src + src_size - src_stride);
605 int32_t src_line_gap = ((int32_t)src_stride + line_size) >> 2;
606 int32_t dest_line_gap = ((int32_t)dest_stride - (int32_t)line_size) >> 3;
608 destaddr = destaddr & 0x7FFFF8;
610 for( i=destaddr; i < destaddr + dest_stride*(src_size/src_stride); i+= LXDREAM_PAGE_SIZE ) {
611 texcache_invalidate_page( i );
614 banks[0] = (uint32_t *)(pvr2_main_ram + (destaddr >>1));
615 banks[1] = banks[0] + 0x100000;
617 while( dwsrc >= (uint32_t *)src ) {
618 for( j=0; j<line_size; j+=8 ) {
619 *banks[0]++ = *dwsrc++;
620 *banks[1]++ = *dwsrc++;
622 banks[0] += dest_line_gap;
623 banks[1] += dest_line_gap;
624 dwsrc -= src_line_gap;
629 * Copy a pixel buffer to vram, flipping and scaling at the same time. This
630 * is not massively efficient, but it's used pretty rarely.
632 static void pvr2_vram_write_invert_hscale( sh4addr_t destaddr, unsigned char *src, uint32_t src_size,
633 uint32_t line_size, uint32_t dest_stride,
634 uint32_t src_stride, int bpp )
636 unsigned char *dest = pvr2_main_ram + (destaddr & 0x007FFFFF);
637 unsigned char *p = src + src_size - src_stride;
639 unsigned char *s = p, *d = dest;
641 while( s < p+line_size ) {
642 for( i=0; i<bpp; i++ ) {
652 void pvr2_vram64_read( unsigned char *dest, sh4addr_t srcaddr, uint32_t length )
654 int bank_flag = (srcaddr & 0x04) >> 2;
659 srcaddr = srcaddr & 0x7FFFFF;
660 if( srcaddr + length > 0x800000 )
661 length = 0x800000 - srcaddr;
663 banks[0] = ((uint32_t *)(pvr2_main_ram + ((srcaddr&0x007FFFF8)>>1)));
664 banks[1] = banks[0] + 0x100000;
668 /* Handle non-aligned start of source */
669 if( srcaddr & 0x03 ) {
670 char *src = ((char *)banks[bank_flag]) + (srcaddr & 0x03);
671 for( i= srcaddr & 0x03; i < 4 && length > 0; i++, length-- ) {
674 bank_flag = !bank_flag;
677 dwdest = (uint32_t *)dest;
678 while( length >= 4 ) {
679 *dwdest++ = *banks[bank_flag]++;
680 bank_flag = !bank_flag;
684 /* Handle non-aligned end of source */
686 dest = (unsigned char *)dwdest;
687 unsigned char *src = (unsigned char *)banks[bank_flag];
688 while( length-- > 0 ) {
694 void pvr2_vram64_dump_file( sh4addr_t addr, uint32_t length, gchar *filename )
696 uint32_t tmp[length>>2];
697 FILE *f = fopen(filename, "wo");
701 ERROR( "Unable to write to dump file '%s' (%s)", filename, strerror(errno) );
704 pvr2_vram64_read( (unsigned char *)tmp, addr, length );
705 fprintf( f, "%08X\n", addr );
706 for( i =0; i<length>>2; i+=8 ) {
707 for( j=i; j<i+8; j++ ) {
709 fprintf( f, " %08X", tmp[j] );
718 void pvr2_vram64_dump( sh4addr_t addr, uint32_t length, FILE *f )
720 unsigned char tmp[length];
721 pvr2_vram64_read( tmp, addr, length );
722 fwrite_dump( tmp, length, f );
728 * Flush the indicated render buffer back to PVR. Caller is responsible for
729 * tracking whether there is actually anything in the buffer.
731 * FIXME: Handle horizontal scaler
733 * @param buffer A render buffer indicating the address to store to, and the
734 * format the data needs to be in.
736 void pvr2_render_buffer_copy_to_sh4( render_buffer_t buffer )
738 int line_size = buffer->width * colour_formats[buffer->colour_format].bpp;
739 int src_stride = line_size;
740 unsigned char target[buffer->size];
742 display_driver->read_render_buffer( target, buffer, line_size, buffer->colour_format );
744 if( (buffer->scale & 0xFFFF) == 0x0800 )
747 if( (buffer->address & 0xFF000000) == 0x04000000 ) {
748 pvr2_vram64_write_invert( buffer->address, target, buffer->size, line_size,
749 buffer->rowstride, src_stride );
752 if( buffer->scale & SCALER_HSCALE ) {
753 pvr2_vram_write_invert_hscale( buffer->address, target, buffer->size, line_size, buffer->rowstride,
754 src_stride, colour_formats[buffer->colour_format].bpp );
756 pvr2_vram_write_invert( buffer->address, target, buffer->size, line_size, buffer->rowstride,
760 buffer->flushed = TRUE;
.