Search
lxdream.org :: lxdream/src/pvr2/pvr2.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/pvr2/pvr2.c
changeset 133:249aeda31f02
prev127:4ba79389bb6d
next144:7f0714e89aaa
author nkeynes
date Thu Mar 30 11:30:59 2006 +0000 (14 years ago)
permissions -rw-r--r--
last change Unfubar the pvr event generation
Move state into pvr2_state structure for ease of save/load
file annotate diff log raw
1.1 --- a/src/pvr2/pvr2.c Thu Mar 23 13:19:15 2006 +0000
1.2 +++ b/src/pvr2/pvr2.c Thu Mar 30 11:30:59 2006 +0000
1.3 @@ -1,7 +1,7 @@
1.4 /**
1.5 - * $Id: pvr2.c,v 1.21 2006-03-23 13:19:15 nkeynes Exp $
1.6 + * $Id: pvr2.c,v 1.22 2006-03-30 11:30:59 nkeynes Exp $
1.7 *
1.8 - * PVR2 (Video) Core MMIO registers.
1.9 + * PVR2 (Video) Core module implementation and MMIO registers.
1.10 *
1.11 * Copyright (c) 2005 Nathan Keynes.
1.12 *
1.13 @@ -28,18 +28,20 @@
1.14
1.15 char *video_base;
1.16
1.17 -void pvr2_init( void );
1.18 -uint32_t pvr2_run_slice( uint32_t );
1.19 +static void pvr2_init( void );
1.20 +static void pvr2_reset( void );
1.21 +static uint32_t pvr2_run_slice( uint32_t );
1.22 +static void pvr2_save_state( FILE *f );
1.23 +static int pvr2_load_state( FILE *f );
1.24 +
1.25 void pvr2_display_frame( void );
1.26
1.27 -/**
1.28 - * Current PVR2 ram address of the data (if any) currently held in the
1.29 - * OpenGL buffers.
1.30 - */
1.31 +struct dreamcast_module pvr2_module = { "PVR2", pvr2_init, pvr2_reset, NULL,
1.32 + pvr2_run_slice, NULL,
1.33 + pvr2_save_state, pvr2_load_state };
1.34 +
1.35
1.36 video_driver_t video_driver = NULL;
1.37 -struct video_buffer video_buffer[2];
1.38 -int video_buffer_idx = 0;
1.39
1.40 struct video_timing {
1.41 int fields_per_second;
1.42 @@ -48,21 +50,90 @@
1.43 int line_time_ns;
1.44 };
1.45
1.46 -struct video_timing pal_timing = { 50, 625, 50, 32000 };
1.47 +struct video_timing pal_timing = { 50, 625, 65, 32000 };
1.48 struct video_timing ntsc_timing= { 60, 525, 65, 31746 };
1.49
1.50 -struct dreamcast_module pvr2_module = { "PVR2", pvr2_init, NULL, NULL,
1.51 - pvr2_run_slice, NULL,
1.52 - NULL, NULL };
1.53 +struct pvr2_state {
1.54 + uint32_t frame_count;
1.55 + uint32_t line_count;
1.56 + uint32_t line_remainder;
1.57 + uint32_t irq_vpos1;
1.58 + uint32_t irq_vpos2;
1.59 + gboolean retrace;
1.60 + struct video_timing timing;
1.61 +} pvr2_state;
1.62
1.63 -void pvr2_init( void )
1.64 +struct video_buffer video_buffer[2];
1.65 +int video_buffer_idx = 0;
1.66 +
1.67 +static void pvr2_init( void )
1.68 {
1.69 register_io_region( &mmio_region_PVR2 );
1.70 register_io_region( &mmio_region_PVR2PAL );
1.71 register_io_region( &mmio_region_PVR2TA );
1.72 video_base = mem_get_region_by_name( MEM_REGION_VIDEO );
1.73 + texcache_init();
1.74 + pvr2_reset();
1.75 +}
1.76 +
1.77 +static void pvr2_reset( void )
1.78 +{
1.79 + pvr2_state.line_count = 0;
1.80 + pvr2_state.line_remainder = 0;
1.81 + pvr2_state.irq_vpos1 = 0;
1.82 + pvr2_state.irq_vpos2 = 0;
1.83 + pvr2_state.retrace = FALSE;
1.84 + pvr2_state.timing = ntsc_timing;
1.85 + video_buffer_idx = 0;
1.86 +
1.87 + pvr2_ta_init();
1.88 pvr2_render_init();
1.89 - texcache_init();
1.90 + texcache_flush();
1.91 +}
1.92 +
1.93 +static void pvr2_save_state( FILE *f )
1.94 +{
1.95 + fwrite( &pvr2_state, sizeof(pvr2_state), 1, f );
1.96 +}
1.97 +
1.98 +static int pvr2_load_state( FILE *f )
1.99 +{
1.100 + fread( &pvr2_state, sizeof(pvr2_state), 1, f );
1.101 +}
1.102 +
1.103 +static uint32_t pvr2_run_slice( uint32_t nanosecs )
1.104 +{
1.105 + pvr2_state.line_remainder += nanosecs;
1.106 + while( pvr2_state.line_remainder >= pvr2_state.timing.line_time_ns ) {
1.107 + pvr2_state.line_remainder -= pvr2_state.timing.line_time_ns;
1.108 +
1.109 + pvr2_state.line_count++;
1.110 + if( pvr2_state.line_count == pvr2_state.timing.total_lines ) {
1.111 + asic_event( EVENT_RETRACE );
1.112 + pvr2_state.line_count = 0;
1.113 + pvr2_state.retrace = TRUE;
1.114 + }
1.115 +
1.116 + if( pvr2_state.line_count == pvr2_state.irq_vpos1 ) {
1.117 + asic_event( EVENT_SCANLINE1 );
1.118 + }
1.119 + if( pvr2_state.line_count == pvr2_state.irq_vpos2 ) {
1.120 + asic_event( EVENT_SCANLINE2 );
1.121 + }
1.122 +
1.123 + if( pvr2_state.line_count == pvr2_state.timing.retrace_lines ) {
1.124 + if( pvr2_state.retrace ) {
1.125 + pvr2_display_frame();
1.126 + pvr2_state.retrace = FALSE;
1.127 + }
1.128 + }
1.129 + }
1.130 + return nanosecs;
1.131 +}
1.132 +
1.133 +int pvr2_get_frame_count()
1.134 +{
1.135 + return pvr2_state.frame_count;
1.136 }
1.137
1.138 void video_set_driver( video_driver_t driver )
1.139 @@ -78,46 +149,6 @@
1.140 texcache_gl_init();
1.141 }
1.142
1.143 -uint32_t pvr2_line_count = 0;
1.144 -uint32_t pvr2_line_remainder = 0;
1.145 -uint32_t pvr2_irq_vpos1 = 0;
1.146 -uint32_t pvr2_irq_vpos2 = 0;
1.147 -gboolean pvr2_retrace = FALSE;
1.148 -struct video_timing *pvr2_timing = &ntsc_timing;
1.149 -uint32_t pvr2_time_counter = 0;
1.150 -uint32_t pvr2_frame_counter = 0;
1.151 -uint32_t pvr2_time_per_frame = 20000000;
1.152 -
1.153 -uint32_t pvr2_run_slice( uint32_t nanosecs )
1.154 -{
1.155 - pvr2_line_remainder += nanosecs;
1.156 - while( pvr2_line_remainder >= pvr2_timing->line_time_ns ) {
1.157 - pvr2_line_remainder -= pvr2_timing->line_time_ns;
1.158 - pvr2_line_count++;
1.159 - if( pvr2_line_count == pvr2_irq_vpos1 ) {
1.160 - asic_event( EVENT_SCANLINE1 );
1.161 - }
1.162 - if( pvr2_line_count == pvr2_irq_vpos2 ) {
1.163 - asic_event( EVENT_SCANLINE2 );
1.164 - }
1.165 - if( pvr2_line_count == pvr2_timing->total_lines ) {
1.166 - asic_event( EVENT_RETRACE );
1.167 - pvr2_line_count = 0;
1.168 - pvr2_retrace = TRUE;
1.169 - } else if( pvr2_line_count == pvr2_timing->retrace_lines ) {
1.170 - if( pvr2_retrace ) {
1.171 - pvr2_display_frame();
1.172 - pvr2_retrace = FALSE;
1.173 - }
1.174 - }
1.175 - }
1.176 - return nanosecs;
1.177 -}
1.178 -
1.179 -uint32_t vid_stride, vid_lpf, vid_ppl, vid_hres, vid_vres, vid_col;
1.180 -int interlaced, bChanged = 1, bEnabled = 0, vid_size = 0;
1.181 -char *frame_start; /* current video start address (in real memory) */
1.182 -
1.183 /**
1.184 * Display the next frame, copying the current contents of video ram to
1.185 * the window. If the video configuration has changed, first recompute the
1.186 @@ -140,7 +171,7 @@
1.187 video_buffer_idx = !video_buffer_idx;
1.188 video_buffer_t last = &video_buffer[video_buffer_idx];
1.189 buffer->rowstride = (vid_ppl + vid_stride) << 2;
1.190 - buffer->data = frame_start = video_base + MMIO_READ( PVR2, DISPADDR1 );
1.191 + buffer->data = video_base + MMIO_READ( PVR2, DISPADDR1 );
1.192 buffer->vres = vid_lpf;
1.193 if( interlaced ) buffer->vres <<= 1;
1.194 switch( (dispmode & DISPMODE_COL) >> 2 ) {
1.195 @@ -180,10 +211,7 @@
1.196 video_buffer_idx = 0;
1.197 video_buffer[0].hres = video_buffer[0].vres = 0;
1.198 }
1.199 - pvr2_frame_counter++;
1.200 - asic_event( EVENT_SCANLINE1 );
1.201 - asic_event( EVENT_SCANLINE2 );
1.202 - asic_event( EVENT_RETRACE );
1.203 + pvr2_state.frame_count++;
1.204 }
1.205
1.206 void mmio_region_PVR2_write( uint32_t reg, uint32_t val )
1.207 @@ -201,14 +229,14 @@
1.208
1.209 switch(reg) {
1.210 case DISPADDR1:
1.211 - if( pvr2_retrace ) {
1.212 + if( pvr2_state.retrace ) {
1.213 pvr2_display_frame();
1.214 - pvr2_retrace = FALSE;
1.215 + pvr2_state.retrace = FALSE;
1.216 }
1.217 break;
1.218 case VPOS_IRQ:
1.219 - pvr2_irq_vpos1 = (val >> 16) & 0x03FF;
1.220 - pvr2_irq_vpos2 = val & 0x03FF;
1.221 + pvr2_state.irq_vpos1 = (val >> 16) & 0x03FF;
1.222 + pvr2_state.irq_vpos2 = val & 0x03FF;
1.223 break;
1.224 case TAINIT:
1.225 if( val & 0x80000000 )
.