filename | src/pvr2/pvr2.c |
changeset | 27:1ef09a52cd1e |
prev | 23:1ec3acd0594d |
next | 30:89b30313d757 |
author | nkeynes |
date | Sun Dec 25 01:28:39 2005 +0000 (16 years ago) |
permissions | -rw-r--r-- |
last change | Refactor all the GUI bits out of the main directory (except for a couple lingering temporarily in loader.c Fix a few timeslice issues |
view | annotate | diff | log | raw |
1 #include "dream.h"
2 #include "video.h"
3 #include "mem.h"
4 #include "asic.h"
5 #include "modules.h"
6 #include "pvr2.h"
7 #define MMIO_IMPL
8 #include "pvr2.h"
10 char *video_base;
12 void pvr2_init( void );
13 int pvr2_run_slice( int );
14 void pvr2_next_frame( void );
16 struct dreamcast_module pvr2_module = { "PVR2", pvr2_init, NULL, NULL,
17 pvr2_run_slice, NULL,
18 NULL, NULL };
20 void pvr2_init( void )
21 {
22 register_io_region( &mmio_region_PVR2 );
23 video_base = mem_get_region_by_name( MEM_REGION_VIDEO );
24 }
26 uint32_t pvr2_time_counter = 0;
27 uint32_t pvr2_time_per_frame = 20000;
29 int pvr2_run_slice( int microsecs )
30 {
31 pvr2_time_counter += microsecs;
32 if( pvr2_time_counter >= pvr2_time_per_frame ) {
33 pvr2_next_frame();
34 pvr2_time_counter -= pvr2_time_per_frame;
35 }
36 return microsecs;
37 }
39 uint32_t vid_stride, vid_lpf, vid_ppl, vid_hres, vid_vres, vid_col;
40 int interlaced, bChanged = 1, bEnabled = 0, vid_size = 0;
41 char *frame_start; /* current video start address (in real memory) */
43 /*
44 * Display the next frame, copying the current contents of video ram to
45 * the window. If the video configuration has changed, first recompute the
46 * new frame size/depth.
47 */
48 void pvr2_next_frame( void )
49 {
50 if( bChanged ) {
51 int dispsize = MMIO_READ( PVR2, DISPSIZE );
52 int dispmode = MMIO_READ( PVR2, DISPMODE );
53 int vidcfg = MMIO_READ( PVR2, VIDCFG );
54 vid_stride = ((dispsize & DISPSIZE_MODULO) >> 20) - 1;
55 vid_lpf = ((dispsize & DISPSIZE_LPF) >> 10) + 1;
56 vid_ppl = ((dispsize & DISPSIZE_PPL)) + 1;
57 vid_col = (dispmode & DISPMODE_COL);
58 frame_start = video_base + MMIO_READ( PVR2, DISPADDR1 );
59 interlaced = (vidcfg & VIDCFG_I ? 1 : 0);
60 bEnabled = (dispmode & DISPMODE_DE) && (vidcfg & VIDCFG_VO ) ? 1 : 0;
61 vid_size = (vid_ppl * vid_lpf) << (interlaced ? 3 : 2);
62 vid_hres = vid_ppl;
63 vid_vres = vid_lpf;
64 if( interlaced ) vid_vres <<= 1;
65 switch( vid_col ) {
66 case MODE_RGB15:
67 case MODE_RGB16: vid_hres <<= 1; break;
68 case MODE_RGB24: vid_hres *= 3; break;
69 case MODE_RGB32: vid_hres <<= 2; break;
70 }
71 vid_hres >>= 2;
72 video_update_size( vid_hres, vid_vres, vid_col );
73 bChanged = 0;
74 }
75 if( bEnabled ) {
76 /* Assume bit depths match for now... */
77 memcpy( video_data, frame_start, vid_size );
78 } else {
79 memset( video_data, 0, vid_size );
80 }
81 video_update_frame();
82 asic_event( EVENT_SCANLINE1 );
83 asic_event( EVENT_SCANLINE2 );
84 asic_event( EVENT_RETRACE );
85 }
87 void mmio_region_PVR2_write( uint32_t reg, uint32_t val )
88 {
89 if( reg >= 0x200 && reg < 0x600 ) { /* Fog table */
90 MMIO_WRITE( PVR2, reg, val );
91 /* I don't want to hear about these */
92 return;
93 }
95 INFO( "PVR2 write to %08X <= %08X [%s: %s]", reg, val,
96 MMIO_REGID(PVR2,reg), MMIO_REGDESC(PVR2,reg) );
98 switch(reg) {
99 case DISPSIZE: bChanged = 1;
100 case DISPMODE: bChanged = 1;
101 case DISPADDR1: bChanged = 1;
102 case DISPADDR2: bChanged = 1;
103 case VIDCFG: bChanged = 1;
104 break;
106 }
107 MMIO_WRITE( PVR2, reg, val );
108 }
110 MMIO_REGION_READ_FN( PVR2, reg )
111 {
112 switch( reg ) {
113 case BEAMPOS:
114 return sh4r.icount&0x20 ? 0x2000 : 1;
115 default:
116 return MMIO_READ( PVR2, reg );
117 }
118 }
120 void pvr2_set_base_address( uint32_t base )
121 {
122 mmio_region_PVR2_write( DISPADDR1, base );
123 }
.