Search
lxdream.org :: lxdream/src/pvr2/pvr2.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/pvr2/pvr2.c
changeset 23:1ec3acd0594d
prev19:9da7a8e38f9d
next27:1ef09a52cd1e
author nkeynes
date Fri Dec 23 11:44:55 2005 +0000 (16 years ago)
permissions -rw-r--r--
last change Start of "real" time slices, general structure in place now
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 void 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 void 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 }
    38 uint32_t vid_stride, vid_lpf, vid_ppl, vid_hres, vid_vres, vid_col;
    39 int interlaced, bChanged = 1, bEnabled = 0, vid_size = 0;
    40 char *frame_start; /* current video start address (in real memory) */
    42 /*
    43  * Display the next frame, copying the current contents of video ram to
    44  * the window. If the video configuration has changed, first recompute the
    45  * new frame size/depth.
    46  */
    47 void pvr2_next_frame( void )
    48 {
    49     if( bChanged ) {
    50         int dispsize = MMIO_READ( PVR2, DISPSIZE );
    51         int dispmode = MMIO_READ( PVR2, DISPMODE );
    52         int vidcfg = MMIO_READ( PVR2, VIDCFG );
    53         vid_stride = ((dispsize & DISPSIZE_MODULO) >> 20) - 1;
    54         vid_lpf = ((dispsize & DISPSIZE_LPF) >> 10) + 1;
    55         vid_ppl = ((dispsize & DISPSIZE_PPL)) + 1;
    56         vid_col = (dispmode & DISPMODE_COL);
    57         frame_start = video_base + MMIO_READ( PVR2, DISPADDR1 );
    58         interlaced = (vidcfg & VIDCFG_I ? 1 : 0);
    59         bEnabled = (dispmode & DISPMODE_DE) && (vidcfg & VIDCFG_VO ) ? 1 : 0;
    60         vid_size = (vid_ppl * vid_lpf) << (interlaced ? 3 : 2);
    61         vid_hres = vid_ppl;
    62         vid_vres = vid_lpf;
    63         if( interlaced ) vid_vres <<= 1;
    64         switch( vid_col ) {
    65             case MODE_RGB15:
    66             case MODE_RGB16: vid_hres <<= 1; break;
    67             case MODE_RGB24: vid_hres *= 3; break;
    68             case MODE_RGB32: vid_hres <<= 2; break;
    69         }
    70         vid_hres >>= 2;
    71         video_update_size( vid_hres, vid_vres, vid_col );
    72         bChanged = 0;
    73     }
    74     if( bEnabled ) {
    75         /* Assume bit depths match for now... */
    76         memcpy( video_data, frame_start, vid_size );
    77     } else {
    78         memset( video_data, 0, vid_size );
    79     }
    80     video_update_frame();
    81     asic_event( EVENT_SCANLINE1 );
    82     asic_event( EVENT_SCANLINE2 );
    83     asic_event( EVENT_RETRACE );
    84 }
    86 void mmio_region_PVR2_write( uint32_t reg, uint32_t val )
    87 {
    88     if( reg >= 0x200 && reg < 0x600 ) { /* Fog table */
    89         MMIO_WRITE( PVR2, reg, val );
    90         /* I don't want to hear about these */
    91         return;
    92     }
    94     INFO( "PVR2 write to %08X <= %08X [%s: %s]", reg, val, 
    95           MMIO_REGID(PVR2,reg), MMIO_REGDESC(PVR2,reg) );
    97     switch(reg) {
    98         case DISPSIZE: bChanged = 1;
    99         case DISPMODE: bChanged = 1;
   100         case DISPADDR1: bChanged = 1;
   101         case DISPADDR2: bChanged = 1;
   102         case VIDCFG: bChanged = 1;
   103             break;
   105     }
   106     MMIO_WRITE( PVR2, reg, val );
   107 }
   109 MMIO_REGION_READ_FN( PVR2, reg )
   110 {
   111     switch( reg ) {
   112         case BEAMPOS:
   113             return sh4r.icount&0x20 ? 0x2000 : 1;
   114         default:
   115             return MMIO_READ( PVR2, reg );
   116     }
   117 }
   119 void pvr2_set_base_address( uint32_t base ) 
   120 {
   121     mmio_region_PVR2_write( DISPADDR1, base );
   122 }
.