2 * $Id: pvr2.c,v 1.9 2005-12-25 08:24:07 nkeynes Exp $
4 * PVR2 (Video) MMIO and supporting functions.
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.
30 void pvr2_init( void );
31 uint32_t pvr2_run_slice( uint32_t );
32 void pvr2_next_frame( void );
34 struct dreamcast_module pvr2_module = { "PVR2", pvr2_init, NULL, NULL,
38 void pvr2_init( void )
40 register_io_region( &mmio_region_PVR2 );
41 video_base = mem_get_region_by_name( MEM_REGION_VIDEO );
44 uint32_t pvr2_time_counter = 0;
45 uint32_t pvr2_time_per_frame = 20000000;
47 uint32_t pvr2_run_slice( uint32_t nanosecs )
49 pvr2_time_counter += nanosecs;
50 while( pvr2_time_counter >= pvr2_time_per_frame ) {
52 pvr2_time_counter -= pvr2_time_per_frame;
57 uint32_t vid_stride, vid_lpf, vid_ppl, vid_hres, vid_vres, vid_col;
58 int interlaced, bChanged = 1, bEnabled = 0, vid_size = 0;
59 char *frame_start; /* current video start address (in real memory) */
62 * Display the next frame, copying the current contents of video ram to
63 * the window. If the video configuration has changed, first recompute the
64 * new frame size/depth.
66 void pvr2_next_frame( void )
69 int dispsize = MMIO_READ( PVR2, DISPSIZE );
70 int dispmode = MMIO_READ( PVR2, DISPMODE );
71 int vidcfg = MMIO_READ( PVR2, VIDCFG );
72 vid_stride = ((dispsize & DISPSIZE_MODULO) >> 20) - 1;
73 vid_lpf = ((dispsize & DISPSIZE_LPF) >> 10) + 1;
74 vid_ppl = ((dispsize & DISPSIZE_PPL)) + 1;
75 vid_col = (dispmode & DISPMODE_COL);
76 frame_start = video_base + MMIO_READ( PVR2, DISPADDR1 );
77 interlaced = (vidcfg & VIDCFG_I ? 1 : 0);
78 bEnabled = (dispmode & DISPMODE_DE) && (vidcfg & VIDCFG_VO ) ? 1 : 0;
79 vid_size = (vid_ppl * vid_lpf) << (interlaced ? 3 : 2);
82 if( interlaced ) vid_vres <<= 1;
85 case MODE_RGB16: vid_hres <<= 1; break;
86 case MODE_RGB24: vid_hres *= 3; break;
87 case MODE_RGB32: vid_hres <<= 2; break;
90 video_update_size( vid_hres, vid_vres, vid_col );
94 /* Assume bit depths match for now... */
95 memcpy( video_data, frame_start, vid_size );
97 memset( video_data, 0, vid_size );
100 asic_event( EVENT_SCANLINE1 );
101 asic_event( EVENT_SCANLINE2 );
102 asic_event( EVENT_RETRACE );
105 void mmio_region_PVR2_write( uint32_t reg, uint32_t val )
107 if( reg >= 0x200 && reg < 0x600 ) { /* Fog table */
108 MMIO_WRITE( PVR2, reg, val );
109 /* I don't want to hear about these */
113 INFO( "PVR2 write to %08X <= %08X [%s: %s]", reg, val,
114 MMIO_REGID(PVR2,reg), MMIO_REGDESC(PVR2,reg) );
117 case DISPSIZE: bChanged = 1;
118 case DISPMODE: bChanged = 1;
119 case DISPADDR1: bChanged = 1;
120 case DISPADDR2: bChanged = 1;
121 case VIDCFG: bChanged = 1;
125 MMIO_WRITE( PVR2, reg, val );
128 MMIO_REGION_READ_FN( PVR2, reg )
132 return sh4r.icount&0x20 ? 0x2000 : 1;
134 return MMIO_READ( PVR2, reg );
138 void pvr2_set_base_address( uint32_t base )
140 mmio_region_PVR2_write( DISPADDR1, base );
.