src/mess/video/vdc.c
| r903 | r904 | |
| 1 | | #include <assert.h> |
| 2 | | |
| 3 | 1 | #include "driver.h" |
| 4 | | #include "video/generic.h" |
| 5 | 2 | #include "video/vdc.h" |
| 6 | 3 | |
| 7 | 4 | /* Our VDP context */ |
| r903 | r904 | |
| 13 | 10 | void pce_refresh_sprites(int bitmap_line, int line); |
| 14 | 11 | void vdc_do_dma(void); |
| 15 | 12 | |
| 13 | INTERRUPT_GEN( pce_interrupt ) |
| 14 | { |
| 15 | int ret = 0; |
| 16 | |
| 17 | if(vdc.curline==0) |
| 18 | { |
| 19 | //state is now in the VDS region, nothing even tries to draw here. |
| 20 | vdc.top_blanking=(vdc.vdc_data[VPR].b.l&0x1F)+1; |
| 21 | vdc.top_overscan=(vdc.vdc_data[VPR].b.h)+2; |
| 22 | vdc.active_lines = vdc.physical_height = 1 + ( vdc.vdc_data[VDW].w & 0x01FF ); |
| 23 | vdc.bottomfill=vdc.vdc_data[VCR].b.l; |
| 24 | } |
| 25 | |
| 26 | if ( vdc.curline < vdc.top_blanking ) { |
| 27 | /* We are in the top blanking area */ |
| 28 | draw_black_line( vdc.curline ); |
| 29 | } else if ( vdc.curline < vdc.top_blanking + vdc.top_overscan ) { |
| 30 | /* We are in the top overscan area */ |
| 31 | draw_overscan_line( vdc.curline ); |
| 32 | } else if ( vdc.curline < vdc.top_blanking + vdc.top_overscan + vdc.active_lines ) { |
| 33 | /* We are in the active screen area */ |
| 34 | pce_refresh_line( vdc.curline, vdc.curline - ( vdc.top_blanking + vdc.top_overscan ) ); |
| 35 | } else { |
| 36 | /* We are in the bottom blanking area */ |
| 37 | draw_overscan_line( vdc.curline ); |
| 38 | } |
| 39 | |
| 40 | /* bump current scanline */ |
| 41 | vdc.curline = (vdc.curline + 1) % VDC_LPF; |
| 42 | |
| 43 | if ( vdc.curline == vdc.top_blanking + vdc.top_overscan ) { |
| 44 | vdc.y_scroll = vdc.vdc_data[BYR].w; |
| 45 | } |
| 46 | |
| 47 | if ( vdc.curline == vdc.top_blanking + vdc.top_overscan + vdc.active_lines ) { |
| 48 | if ( vdc.bottomfill != 0 ) { |
| 49 | vdc.status |= VDC_VD; |
| 50 | if ( vdc.vdc_data[CR].w & CR_VR ) |
| 51 | ret = 1; |
| 52 | |
| 53 | /* do VRAM > SATB DMA if the enable bit is set or the DVSSR reg. was written to */ |
| 54 | if( ( vdc.vdc_data[DCR].w & DCR_DSR ) || vdc.dvssr_write ) { |
| 55 | int i; |
| 56 | if ( vdc.dvssr_write ) |
| 57 | vdc.dvssr_write = 0; |
| 58 | |
| 59 | for( i = 0; i < 256; i++ ) { |
| 60 | vdc.sprite_ram[i] = ( vdc.vram[ ( vdc.vdc_data[DVSSR].w << 1 ) + i * 2 + 1 ] << 8 ) | vdc.vram[ ( vdc.vdc_data[DVSSR].w << 1 ) + i * 2 ]; |
| 61 | } |
| 62 | |
| 63 | vdc.status |= VDC_DS; /* set satb done flag */ |
| 64 | |
| 65 | /* generate interrupt if needed */ |
| 66 | if ( vdc.vdc_data[DCR].w & DCR_DSC ) |
| 67 | ret = 1; |
| 68 | } |
| 69 | } |
| 70 | } |
| 71 | |
| 72 | /* generate interrupt on line compare if necessary */ |
| 73 | if(vdc.vdc_data[CR].w & CR_RC) |
| 74 | if( vdc.curline == ( ( ( vdc.vdc_data[RCR].w-64 ) + vdc.top_blanking + vdc.top_overscan ) % ( VDC_LPF + 1 ) )) |
| 75 | { |
| 76 | vdc.status |= VDC_RR; |
| 77 | ret = 1; |
| 78 | } |
| 79 | |
| 80 | /* handle frame events */ |
| 81 | if(vdc.curline == VDC_LPF - 1 && ( vdc.bottomfill == 0 || vdc.top_overscan + vdc.top_blanking + vdc.active_lines >= VDC_LPF ) ) |
| 82 | { |
| 83 | vdc.status |= VDC_VD; /* set vblank flag */ |
| 84 | |
| 85 | /* do VRAM > SATB DMA if the enable bit is set or the DVSSR reg. was written to */ |
| 86 | if((vdc.vdc_data[DCR].w & DCR_DSR) || vdc.dvssr_write) |
| 87 | { |
| 88 | int i; |
| 89 | if(vdc.dvssr_write) vdc.dvssr_write = 0; |
| 90 | #ifdef MAME_DEBUG |
| 91 | assert(((vdc.vdc_data[DVSSR].w<<1) + 512) <= 0x10000); |
| 92 | #endif |
| 93 | for( i = 0; i < 256; i++ ) { |
| 94 | vdc.sprite_ram[i] = ( vdc.vram[ ( vdc.vdc_data[DVSSR].w << 1 ) + i * 2 + 1 ] << 8 ) | vdc.vram[ ( vdc.vdc_data[DVSSR].w << 1 ) + i * 2 ]; |
| 95 | } |
| 96 | |
| 97 | vdc.status |= VDC_DS; /* set satb done flag */ |
| 98 | |
| 99 | /* generate interrupt if needed */ |
| 100 | if(vdc.vdc_data[DCR].w & DCR_DSC) |
| 101 | { |
| 102 | ret = 1; |
| 103 | } |
| 104 | } |
| 105 | |
| 106 | if(vdc.vdc_data[CR].w & CR_VR) /* generate IRQ1 if enabled */ |
| 107 | { |
| 108 | ret = 1; |
| 109 | } |
| 110 | } |
| 111 | if (ret) |
| 112 | cpunum_set_input_line(0, 0, HOLD_LINE); |
| 113 | } |
| 114 | |
| 16 | 115 | VIDEO_START( pce ) |
| 17 | 116 | { |
| 18 | 117 | logerror("*** pce_vh_start\n"); |
| r903 | r904 | |
| 38 | 137 | |
| 39 | 138 | void draw_black_line(int line) |
| 40 | 139 | { |
| 41 | | /* don't know which pen is really black, so it currently uses BG pen 0*/ |
| 42 | 140 | int i; |
| 43 | 141 | |
| 44 | 142 | /* our line buffer */ |
| 45 | 143 | UINT16 *line_buffer = BITMAP_ADDR16( vdc.bmp, line, 0 ); |
| 46 | 144 | |
| 47 | 145 | for( i=0; i< Machine->screen[0].width; i++ ) |
| 48 | | line_buffer[i] = Machine->pens[0]; |
| 146 | line_buffer[i] = get_black_pen( Machine ); |
| 49 | 147 | } |
| 50 | 148 | |
| 51 | 149 | void draw_overscan_line(int line) |
| r903 | r904 | |
| 55 | 153 | /* our line buffer */ |
| 56 | 154 | UINT16 *line_buffer = BITMAP_ADDR16( vdc.bmp, line, 0 ); |
| 57 | 155 | |
| 58 | | for( i=0; i< Machine->screen[0].width; i++ ) |
| 156 | for ( i = 0; i < 86; i++ ) |
| 59 | 157 | line_buffer[i] = Machine->pens[0x100]; |
| 158 | for ( i = 86; i < 86 + 512; i++ ) |
| 159 | line_buffer[i] = Machine->pens[0]; |
| 160 | for ( i = 86 + 512 ; i < Machine->screen[0].width; i++ ) |
| 161 | line_buffer[i] = Machine->pens[0x100]; |
| 162 | |
| 60 | 163 | } |
| 61 | 164 | |
| 62 | 165 | void vram_write(offs_t offset, UINT8 data) |
src/mess/drivers/pce.c
| r903 | r904 | |
| 40 | 40 | - Violent Soldier: corruption on title screen |
| 41 | 41 | **********************************************************************/ |
| 42 | 42 | |
| 43 | | #include <assert.h> |
| 44 | | |
| 45 | 43 | #include "driver.h" |
| 46 | | #include "video/generic.h" |
| 47 | 44 | #include "video/vdc.h" |
| 48 | 45 | #include "cpu/h6280/h6280.h" |
| 49 | 46 | #include "includes/pce.h" |
| r903 | r904 | |
| 53 | 50 | |
| 54 | 51 | #define MAIN_CLOCK 21477270 |
| 55 | 52 | |
| 56 | | static INTERRUPT_GEN( pce_interrupt ) |
| 57 | | { |
| 58 | | int ret = 0; |
| 59 | | |
| 60 | | /* bump current scanline */ |
| 61 | | vdc.curline = (vdc.curline + 1) % VDC_LPF; |
| 62 | | |
| 63 | | if(vdc.curline==0) |
| 64 | | { |
| 65 | | //state is now in the VDS region, nothing even tries to draw here. |
| 66 | | vdc.top_blanking=(vdc.vdc_data[VPR].b.l&0x1F)+1; |
| 67 | | vdc.top_overscan=(vdc.vdc_data[VPR].b.h)+2; |
| 68 | | vdc.active_lines = vdc.physical_height = 1 + ( vdc.vdc_data[VDW].w & 0x01FF ); |
| 69 | | vdc.bottomfill=vdc.vdc_data[VCR].b.l; |
| 70 | | } |
| 71 | | |
| 72 | | if ( vdc.curline < vdc.top_blanking ) { |
| 73 | | /* We are in the top blanking area */ |
| 74 | | draw_black_line( vdc.curline ); |
| 75 | | } else if ( vdc.curline < vdc.top_blanking + vdc.top_overscan ) { |
| 76 | | /* We are in the top overscan area */ |
| 77 | | draw_overscan_line( vdc.curline ); |
| 78 | | } else if ( vdc.curline < vdc.top_blanking + vdc.top_overscan + vdc.active_lines ) { |
| 79 | | /* We are in the active screen area */ |
| 80 | | if ( vdc.curline == vdc.top_blanking + vdc.top_overscan ) { |
| 81 | | vdc.y_scroll = vdc.vdc_data[BYR].w; |
| 82 | | } |
| 83 | | pce_refresh_line( vdc.curline, vdc.curline - ( vdc.top_blanking + vdc.top_overscan ) ); |
| 84 | | } else { |
| 85 | | /* We are in the bottom blanking area */ |
| 86 | | if ( vdc.curline == vdc.top_blanking + vdc.top_overscan + vdc.active_lines ) { |
| 87 | | if ( vdc.bottomfill != 0 ) { |
| 88 | | vdc.status |= VDC_VD; |
| 89 | | if ( vdc.vdc_data[CR].w & CR_VR ) |
| 90 | | ret = 1; |
| 91 | | |
| 92 | | /* do VRAM > SATB DMA if the enable bit is set or the DVSSR reg. was written to */ |
| 93 | | if( ( vdc.vdc_data[DCR].w & DCR_DSR ) || vdc.dvssr_write ) { |
| 94 | | int i; |
| 95 | | if ( vdc.dvssr_write ) |
| 96 | | vdc.dvssr_write = 0; |
| 97 | | |
| 98 | | for( i = 0; i < 256; i++ ) { |
| 99 | | vdc.sprite_ram[i] = ( vdc.vram[ ( vdc.vdc_data[DVSSR].w << 1 ) + i * 2 + 1 ] << 8 ) | vdc.vram[ ( vdc.vdc_data[DVSSR].w << 1 ) + i * 2 ]; |
| 100 | | } |
| 101 | | |
| 102 | | vdc.status |= VDC_DS; /* set satb done flag */ |
| 103 | | |
| 104 | | /* generate interrupt if needed */ |
| 105 | | if ( vdc.vdc_data[DCR].w & DCR_DSC ) |
| 106 | | ret = 1; |
| 107 | | } |
| 108 | | } |
| 109 | | } |
| 110 | | draw_overscan_line( vdc.curline ); |
| 111 | | } |
| 112 | | |
| 113 | | /* generate interrupt on line compare if necessary */ |
| 114 | | if(vdc.vdc_data[CR].w & CR_RC) |
| 115 | | if( vdc.curline == ( ( ( vdc.vdc_data[RCR].w-64 ) + vdc.top_blanking + vdc.top_overscan ) % ( VDC_LPF + 1 ) )) |
| 116 | | { |
| 117 | | vdc.status |= VDC_RR; |
| 118 | | ret = 1; |
| 119 | | } |
| 120 | | |
| 121 | | /* handle frame events */ |
| 122 | | if(vdc.curline == VDC_LPF - 1 && ( vdc.bottomfill == 0 || vdc.top_overscan + vdc.top_blanking + vdc.active_lines >= VDC_LPF ) ) |
| 123 | | { |
| 124 | | vdc.status |= VDC_VD; /* set vblank flag */ |
| 125 | | |
| 126 | | /* do VRAM > SATB DMA if the enable bit is set or the DVSSR reg. was written to */ |
| 127 | | if((vdc.vdc_data[DCR].w & DCR_DSR) || vdc.dvssr_write) |
| 128 | | { |
| 129 | | int i; |
| 130 | | if(vdc.dvssr_write) vdc.dvssr_write = 0; |
| 131 | | #ifdef MAME_DEBUG |
| 132 | | assert(((vdc.vdc_data[DVSSR].w<<1) + 512) <= 0x10000); |
| 133 | | #endif |
| 134 | | for( i = 0; i < 256; i++ ) { |
| 135 | | vdc.sprite_ram[i] = ( vdc.vram[ ( vdc.vdc_data[DVSSR].w << 1 ) + i * 2 + 1 ] << 8 ) | vdc.vram[ ( vdc.vdc_data[DVSSR].w << 1 ) + i * 2 ]; |
| 136 | | } |
| 137 | | |
| 138 | | vdc.status |= VDC_DS; /* set satb done flag */ |
| 139 | | |
| 140 | | /* generate interrupt if needed */ |
| 141 | | if(vdc.vdc_data[DCR].w & DCR_DSC) |
| 142 | | { |
| 143 | | ret = 1; |
| 144 | | } |
| 145 | | } |
| 146 | | |
| 147 | | if(vdc.vdc_data[CR].w & CR_VR) /* generate IRQ1 if enabled */ |
| 148 | | { |
| 149 | | ret = 1; |
| 150 | | } |
| 151 | | } |
| 152 | | if (ret) |
| 153 | | cpunum_set_input_line(0, 0, HOLD_LINE); |
| 154 | | } |
| 155 | | |
| 156 | 53 | ADDRESS_MAP_START( pce_mem , ADDRESS_SPACE_PROGRAM, 8) |
| 157 | 54 | AM_RANGE( 0x000000, 0x1EDFFF) AM_ROMBANK(1) |
| 158 | 55 | AM_RANGE( 0x1EE000, 0x1EFFFF) AM_RAM AM_BASE( &pce_nvram ) |