From 9c085ae0fa18df54f9cb8356ebbf2ae8bc8099bd Mon Sep 17 00:00:00 2001 From: Angelo Salese Date: Fri, 14 Nov 2008 15:53:19 +0000 Subject: [PATCH] Pre-irq rewrite submission in ST-V driver: * Better management of hblank/vblank bits; * Makes dynamic resolutions to be called with a timer instead of run-time; * Makes dynamic resolutions to not be changed at every frame but only when there's an actual change; This fixes Golden Axe: the Duel gameplay speed at the cost of breaking up Groove on Fight coin counter at start-up. --- src/mame/drivers/stv.c | 14 ++---- src/mame/video/stvvdp1.c | 3 +- src/mame/video/stvvdp2.c | 106 ++++++++++++++++++++++++++++++++------- 3 files changed, 93 insertions(+), 30 deletions(-) diff --git a/src/mame/drivers/stv.c b/src/mame/drivers/stv.c index 8b57a98bf1b..4f9df2452b1 100644 --- a/src/mame/drivers/stv.c +++ b/src/mame/drivers/stv.c @@ -192,7 +192,6 @@ static UINT32* ioga; static UINT16* scsp_regs; static UINT16* sound_ram; -int stv_vblank,stv_hblank; int stv_enable_slave_sh2; /*SMPC stuff*/ static UINT8 NMI_reset; @@ -756,8 +755,6 @@ static INTERRUPT_GEN( stv_interrupt ) { scanline = 261-cpu_getiloops(device); - stv_hblank = 0; - if(scanline == 0) { if(!(stv_scu[40] & 2))/*VBLANK-OUT*/ @@ -765,13 +762,11 @@ static INTERRUPT_GEN( stv_interrupt ) if(LOG_IRQ) logerror ("Interrupt: VBlank-OUT at scanline %04x, Vector 0x41 Level 0x0e\n",scanline); cpu_set_input_line_and_vector(device, 0xe, HOLD_LINE , 0x41); } - stv_vblank = 0; } else if(scanline <= 223 && scanline >= 1)/*Correct?*/ { timer_0++; timer_1++; - stv_hblank = 1; /*TODO: check this...*/ /*Timer 1 handling*/ if((stv_scu[38] & 1)) @@ -816,7 +811,6 @@ static INTERRUPT_GEN( stv_interrupt ) if(LOG_IRQ) logerror ("Interrupt: VBlank IN at scanline %04x, Vector 0x40 Level 0x0f\n",scanline); cpu_set_input_line_and_vector(device, 0xf, HOLD_LINE , 0x40); } - stv_vblank = 1; if(timer_0 == (stv_scu[36] & 0x1ff)) { @@ -2535,8 +2529,8 @@ static MACHINE_START( stv ) state_save_register_global_pointer(smpc_ram, 0x80); state_save_register_global_pointer(stv_scu, 0x100/4); state_save_register_global_pointer(scsp_regs, 0x1000/2); - state_save_register_global(stv_vblank); - state_save_register_global(stv_hblank); +// state_save_register_global(stv_vblank); +// state_save_register_global(stv_hblank); state_save_register_global(stv_enable_slave_sh2); state_save_register_global(NMI_reset); state_save_register_global(en_68k); @@ -2608,8 +2602,8 @@ static MACHINE_DRIVER_START( stv ) MDRV_SCREEN_REFRESH_RATE(60) MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(192)) // guess, needed to force video update after V-Blank OUT interrupt MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB15) - MDRV_SCREEN_SIZE(1024, 1024) - MDRV_SCREEN_VISIBLE_AREA(0*8, 703, 0*8, 512) // we need to use a resolution as high as the max size it can change to + MDRV_SCREEN_SIZE(704, 512) + MDRV_SCREEN_VISIBLE_AREA(0*8, 703, 0*8, 511) // we need to use a resolution as high as the max size it can change to MDRV_PALETTE_LENGTH(2048+(2048*2))//standard palette + extra memory for rgb brightness. MDRV_GFXDECODE(stv) diff --git a/src/mame/video/stvvdp1.c b/src/mame/video/stvvdp1.c index 7dd86ce4500..4d952068907 100644 --- a/src/mame/video/stvvdp1.c +++ b/src/mame/video/stvvdp1.c @@ -26,6 +26,7 @@ static int vdp1_sprite_log = 0; UINT32 *stv_vdp1_vram; static UINT32 *stv_vdp1_regs; UINT8* stv_vdp1_gfx_decode; +extern UINT8 get_vblank(running_machine *machine); static UINT16 *stv_framebuffer[2]; static UINT16 **stv_framebuffer_draw_lines; @@ -294,7 +295,7 @@ WRITE32_HANDLER( stv_vdp1_regs_w ) else { if ( vdp1_sprite_log ) logerror( "VDP1: Access to register TVMR = %1X\n", STV_VDP1_TVMR ); - if ( STV_VDP1_VBE && stv_vblank ) + if ( STV_VDP1_VBE && get_vblank(machine) ) { stv_vdp1_clear_framebuffer_on_next_frame = 1; } diff --git a/src/mame/video/stvvdp2.c b/src/mame/video/stvvdp2.c index c3eb49c217d..a9a12692178 100644 --- a/src/mame/video/stvvdp2.c +++ b/src/mame/video/stvvdp2.c @@ -112,9 +112,13 @@ static UINT8* stv_vdp2_vram_dirty_8x8x8; static UINT8* stv_vdp2_gfx_decode; static int stv_vdp2_render_rbg0; +int stv_hblank,stv_vblank; +int horz_res,vert_res; UINT32* stv_vdp2_cram; static void stv_vdp2_dynamic_res_change(running_machine *machine); +UINT8 get_vblank(running_machine *machine); +UINT8 get_hblank(running_machine *machine); static void refresh_palette_data(running_machine *machine); static int stv_vdp2_window_process(int x,int y); static int stv_vdp2_apply_window_on_layer(rectangle *cliprect); @@ -5260,6 +5264,31 @@ WRITE32_HANDLER ( stv_vdp2_regs_w ) } } +UINT8 get_hblank(running_machine *machine) +{ + static int cur_h; + + rectangle visarea = *video_screen_get_visible_area(machine->primary_screen); + cur_h = video_screen_get_hpos(machine->primary_screen); + + if (cur_h > visarea.max_x) + return 1; + else + return 0; +} + +UINT8 get_vblank(running_machine *machine) +{ + static int cur_v; + rectangle visarea = *video_screen_get_visible_area(machine->primary_screen); + cur_v = video_screen_get_vpos(machine->primary_screen); + + if (cur_v > visarea.max_y) + return 1; + else + return 0; +} + READ32_HANDLER ( stv_vdp2_regs_r ) { // if (offset!=1) if(LOG_VDP2) logerror ("VDP2: Read from Registers, Offset %04x\n",offset); @@ -5267,10 +5296,29 @@ READ32_HANDLER ( stv_vdp2_regs_r ) switch(offset) { case 0x4/4: - /*Screen Status Register*/ + { + /*Screen Status Register*/ + //rectangle visarea = *video_screen_get_visible_area(machine->primary_screen); + + //stv_hblank = 0; + //stv_vblank = 0; + //h = video_screen_get_height(machine->primary_screen); + //w = video_screen_get_width(machine->primary_screen); + //cur_h = video_screen_get_hpos(machine->primary_screen); + //cur_v = video_screen_get_vpos(machine->primary_screen); + + //popmessage("%d %d",cur_h,cur_v); + + //if (cur_h > visarea.max_x) + stv_hblank = get_hblank(machine); + //if (cur_v > visarea.max_y) + stv_vblank = get_vblank(machine); + /*ODD bit*/ + /*VBLANK HBLANK ODD PAL */ stv_vdp2_regs[offset] = (stv_vblank<<19) | (stv_hblank<<18) | (1 << 17) | (0 << 16); - break; + break; + } case 0x8/4: /*H/V Counter Register*/ /*H-Counter V-Counter */ @@ -5348,40 +5396,60 @@ VIDEO_START( stv_vdp2 ) debug.roz = 0; } +/*TODO: frame_period should be different for every kind of resolution (needs tests on actual boards)*/ +/* & height / width not yet understood (docs-wise MUST be bigger than normal visible area)*/ +static TIMER_CALLBACK( dyn_res_change ) +{ + rectangle visarea = *video_screen_get_visible_area(machine->primary_screen); + visarea.min_x = 0; + visarea.max_x = horz_res-1; + visarea.min_y = 0; + visarea.max_y = vert_res-1; + + video_screen_configure(machine->primary_screen, horz_res*2, vert_res+2, &visarea, video_screen_get_frame_period(machine->primary_screen).attoseconds ); +} + static void stv_vdp2_dynamic_res_change(running_machine *machine) { - static UINT16 horz,vert; + static UINT8 old_vres = 0,old_hres = 0; switch( STV_VDP2_VRES & 3 ) { - case 0: vert = 224; break; - case 1: vert = 240; break; - case 2: vert = 256; break; + case 0: vert_res = 224; break; + case 1: vert_res = 240; break; + case 2: vert_res = 256; break; case 3: if(LOG_VDP2) logerror("WARNING: V Res setting (3) not allowed!\n"); - vert = 256; + vert_res = 256; break; } /*Double-density interlace mode,doubles the vertical res*/ - if((STV_VDP2_LSMD & 3) == 3) { vert*=2; } + if((STV_VDP2_LSMD & 3) == 3) { vert_res*=2; } switch( STV_VDP2_HRES & 7 ) { - case 0: horz = 320; break; - case 1: horz = 352; break; - case 2: horz = 640; break; - case 3: horz = 704; break; + case 0: horz_res = 320; break; + case 1: horz_res = 352; break; + case 2: horz_res = 640; break; + case 3: horz_res = 704; break; /*Exclusive modes,they sets the Vertical Resolution without considering the VRES register.*/ - case 4: horz = 320; vert = 480; break; - case 5: horz = 352; vert = 480; break; - case 6: horz = 640; vert = 480; break; - case 7: horz = 704; vert = 480; break; + case 4: horz_res = 320; vert_res = 480; break; + case 5: horz_res = 352; vert_res = 480; break; + case 6: horz_res = 640; vert_res = 480; break; + case 7: horz_res = 704; vert_res = 480; break; } - - video_screen_set_visarea(machine->primary_screen, 0*8, horz-1,0*8, vert-1); - //if(LOG_VDP2) popmessage("%04d %04d",horz-1,vert-1); +// horz_res+=1; +// vert_res*=2; + if(old_vres != vert_res || old_hres != horz_res) + { + timer_set(video_screen_get_time_until_pos(machine->primary_screen, 0, 0), NULL, 0, dyn_res_change); + old_vres = vert_res; + old_hres = horz_res; + } +// video_screen_set_visarea(machine->primary_screen, 0*8, horz_res-1,0*8, vert_res-1); + //if(LOG_VDP2) popmessage("%04d %04d",horz_res-1,vert-1); } /*This is for calculating the rgb brightness*/