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