Search
lxdream.org :: lxdream/src/pvr2/pvr2.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/pvr2/pvr2.c
changeset 27:1ef09a52cd1e
prev23:1ec3acd0594d
next30:89b30313d757
author nkeynes
date Sun Dec 25 04:54:40 2005 +0000 (18 years ago)
permissions -rw-r--r--
last change Set disasm PC on startup
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 }
.