mirror of
https://github.com/holub/mame
synced 2025-05-29 09:03:08 +03:00
Many improvements on the irq handling of the ST-V driver [Angelo Salese,Charles MacDonald]
* Fixed a bug with irq timings; * Added ODD bit emulation; * Fixed vblank period timings; * Optimized a bit the whole interrupt routines,getting a 4x speed gain; * Fixed an irq mask handling bug; (This fixes at least Astra SuperStars and Pebble Beach booting,but the latter still fails the timer 1 irq routines...I need to check why)
This commit is contained in:
parent
1962ffeaf9
commit
4c2953d8ef
@ -195,6 +195,8 @@ static UINT16* scsp_regs;
|
|||||||
static UINT16* sound_ram;
|
static UINT16* sound_ram;
|
||||||
|
|
||||||
int stv_enable_slave_sh2;
|
int stv_enable_slave_sh2;
|
||||||
|
/*VDP2 stuff*/
|
||||||
|
extern int get_vblank_duration(running_machine *machine);
|
||||||
/*SMPC stuff*/
|
/*SMPC stuff*/
|
||||||
static UINT8 NMI_reset;
|
static UINT8 NMI_reset;
|
||||||
static void system_reset(void);
|
static void system_reset(void);
|
||||||
@ -1332,9 +1334,9 @@ static WRITE32_HANDLER( stv_scu_w32 )
|
|||||||
stv_irq.sound_req = (((stv_scu[40] & 0x0040)>>6) ^ 1);
|
stv_irq.sound_req = (((stv_scu[40] & 0x0040)>>6) ^ 1);
|
||||||
stv_irq.smpc = (((stv_scu[40] & 0x0080)>>7)); //NOTE: SCU bug
|
stv_irq.smpc = (((stv_scu[40] & 0x0080)>>7)); //NOTE: SCU bug
|
||||||
stv_irq.pad = (((stv_scu[40] & 0x0100)>>8) ^ 1);
|
stv_irq.pad = (((stv_scu[40] & 0x0100)>>8) ^ 1);
|
||||||
stv_irq.dma_end[0] = (((stv_scu[40] & 0x0200)>>9) ^ 1);
|
stv_irq.dma_end[2] = (((stv_scu[40] & 0x0200)>>9) ^ 1);
|
||||||
stv_irq.dma_end[1] = (((stv_scu[40] & 0x0400)>>10) ^ 1);
|
stv_irq.dma_end[1] = (((stv_scu[40] & 0x0400)>>10) ^ 1);
|
||||||
stv_irq.dma_end[2] = (((stv_scu[40] & 0x0800)>>11) ^ 1);
|
stv_irq.dma_end[0] = (((stv_scu[40] & 0x0800)>>11) ^ 1);
|
||||||
stv_irq.dma_ill = (((stv_scu[40] & 0x1000)>>12) ^ 1);
|
stv_irq.dma_ill = (((stv_scu[40] & 0x1000)>>12) ^ 1);
|
||||||
stv_irq.vdp1_end = (((stv_scu[40] & 0x2000)>>13) ^ 1);
|
stv_irq.vdp1_end = (((stv_scu[40] & 0x2000)>>13) ^ 1);
|
||||||
stv_irq.abus = (((stv_scu[40] & 0x8000)>>15) ^ 1);
|
stv_irq.abus = (((stv_scu[40] & 0x8000)>>15) ^ 1);
|
||||||
@ -1379,9 +1381,9 @@ static WRITE32_HANDLER( stv_scu_w32 )
|
|||||||
stv_irq.sound_req = ((stv_scu[41] & 0x0040)>>6);
|
stv_irq.sound_req = ((stv_scu[41] & 0x0040)>>6);
|
||||||
stv_irq.smpc = ((stv_scu[41] & 0x0080)>>7);
|
stv_irq.smpc = ((stv_scu[41] & 0x0080)>>7);
|
||||||
stv_irq.pad = ((stv_scu[41] & 0x0100)>>8);
|
stv_irq.pad = ((stv_scu[41] & 0x0100)>>8);
|
||||||
stv_irq.dma_end[0] = ((stv_scu[41] & 0x0200)>>9);
|
stv_irq.dma_end[2] = ((stv_scu[41] & 0x0200)>>9);
|
||||||
stv_irq.dma_end[1] = ((stv_scu[41] & 0x0400)>>10);
|
stv_irq.dma_end[1] = ((stv_scu[41] & 0x0400)>>10);
|
||||||
stv_irq.dma_end[2] = ((stv_scu[41] & 0x0800)>>11);
|
stv_irq.dma_end[0] = ((stv_scu[41] & 0x0800)>>11);
|
||||||
stv_irq.dma_ill = ((stv_scu[41] & 0x1000)>>12);
|
stv_irq.dma_ill = ((stv_scu[41] & 0x1000)>>12);
|
||||||
stv_irq.vdp1_end = ((stv_scu[41] & 0x2000)>>13);
|
stv_irq.vdp1_end = ((stv_scu[41] & 0x2000)>>13);
|
||||||
stv_irq.abus = ((stv_scu[41] & 0x8000)>>15);
|
stv_irq.abus = ((stv_scu[41] & 0x8000)>>15);
|
||||||
@ -2611,15 +2613,17 @@ static TIMER_CALLBACK( hblank_in_irq )
|
|||||||
// h = video_screen_get_height(machine->primary_screen);
|
// h = video_screen_get_height(machine->primary_screen);
|
||||||
// w = video_screen_get_width(machine->primary_screen);
|
// w = video_screen_get_width(machine->primary_screen);
|
||||||
|
|
||||||
TIMER_0_IRQ;
|
|
||||||
HBLANK_IN_IRQ;
|
HBLANK_IN_IRQ;
|
||||||
|
TIMER_0_IRQ;
|
||||||
|
|
||||||
if((scanline+1) < v_sync)
|
if(scanline+1 < v_sync)
|
||||||
{
|
{
|
||||||
timer_adjust_oneshot(scan_timer, video_screen_get_time_until_pos(machine->primary_screen, scanline+1, h_sync), scanline+1);
|
if(stv_irq.hblank_in || stv_irq.timer_0)
|
||||||
|
timer_adjust_oneshot(scan_timer, video_screen_get_time_until_pos(machine->primary_screen, scanline+1, h_sync), scanline+1);
|
||||||
/*set the first Timer-1 event*/
|
/*set the first Timer-1 event*/
|
||||||
cur_scan = scanline+1;
|
cur_scan = scanline+1;
|
||||||
timer_adjust_oneshot(t1_timer, video_screen_get_time_until_pos(machine->primary_screen, scanline+1, 0), 0);
|
if(stv_irq.timer_1)
|
||||||
|
timer_adjust_oneshot(t1_timer, video_screen_get_time_until_pos(machine->primary_screen, scanline+1, 0), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
timer_0++;
|
timer_0++;
|
||||||
@ -2631,7 +2635,7 @@ static TIMER_CALLBACK( timer1_irq )
|
|||||||
|
|
||||||
TIMER_1_IRQ;
|
TIMER_1_IRQ;
|
||||||
|
|
||||||
if((cur_point+1) < h_sync)
|
if((cur_point+1) < h_sync && stv_irq.timer_1)
|
||||||
{
|
{
|
||||||
timer_adjust_oneshot(t1_timer, video_screen_get_time_until_pos(machine->primary_screen, cur_scan, cur_point+1), cur_point+1);
|
timer_adjust_oneshot(t1_timer, video_screen_get_time_until_pos(machine->primary_screen, cur_scan, cur_point+1), cur_point+1);
|
||||||
}
|
}
|
||||||
@ -2653,15 +2657,19 @@ static TIMER_CALLBACK( vblank_out_irq )
|
|||||||
static INTERRUPT_GEN( stv_interrupt )
|
static INTERRUPT_GEN( stv_interrupt )
|
||||||
{
|
{
|
||||||
// scanline = 0;
|
// scanline = 0;
|
||||||
h_sync = video_screen_get_height(device->machine->primary_screen)/2;//horz
|
rectangle visarea = *video_screen_get_visible_area(device->machine->primary_screen);
|
||||||
v_sync = video_screen_get_width(device->machine->primary_screen)-2;//vert
|
|
||||||
|
h_sync = visarea.max_x+1;//horz
|
||||||
|
v_sync = visarea.max_y+1;//vert
|
||||||
|
|
||||||
VBLANK_IN_IRQ;
|
VBLANK_IN_IRQ;
|
||||||
|
|
||||||
/*Next V-Blank-OUT event*/
|
/*Next V-Blank-OUT event*/
|
||||||
timer_adjust_oneshot(vblank_out_timer,video_screen_get_time_until_pos(device->machine->primary_screen, 0, 0), 0);
|
if(stv_irq.vblank_out)
|
||||||
|
timer_adjust_oneshot(vblank_out_timer,video_screen_get_time_until_pos(device->machine->primary_screen, 0, 0), 0);
|
||||||
/*Set the first Hblank-IN event*/
|
/*Set the first Hblank-IN event*/
|
||||||
timer_adjust_oneshot(scan_timer, video_screen_get_time_until_pos(device->machine->primary_screen, 0, h_sync), 0);
|
if(stv_irq.hblank_in || stv_irq.timer_0 || stv_irq.timer_1)
|
||||||
|
timer_adjust_oneshot(scan_timer, video_screen_get_time_until_pos(device->machine->primary_screen, 0, h_sync), 0);
|
||||||
|
|
||||||
/*TODO: timing of this one (related to the VDP1 speed)*/
|
/*TODO: timing of this one (related to the VDP1 speed)*/
|
||||||
/* (NOTE: value shouldn't be at h_sync/v_sync position (will break shienryu))*/
|
/* (NOTE: value shouldn't be at h_sync/v_sync position (will break shienryu))*/
|
||||||
|
@ -67,6 +67,9 @@ its not displayed because its priority value is 0.Left-over?
|
|||||||
-scrolling is screen display wise,meaning that a scrolling value is masked with the
|
-scrolling is screen display wise,meaning that a scrolling value is masked with the
|
||||||
screen resolution size values;
|
screen resolution size values;
|
||||||
|
|
||||||
|
-H-Blank bit is INDIPENDENT of the V-Blank bit...trying to fix enable/disable it during V-Blank period
|
||||||
|
causes wrong gameplay speed in Golden Axe:The Duel.
|
||||||
|
|
||||||
-Bitmaps uses transparency pens,examples are:
|
-Bitmaps uses transparency pens,examples are:
|
||||||
\-elandore's energy bars;
|
\-elandore's energy bars;
|
||||||
\-mausuke's foreground(the one used on the playfield)
|
\-mausuke's foreground(the one used on the playfield)
|
||||||
@ -112,13 +115,18 @@ static UINT8* stv_vdp2_vram_dirty_8x8x8;
|
|||||||
static UINT8* stv_vdp2_gfx_decode;
|
static UINT8* stv_vdp2_gfx_decode;
|
||||||
|
|
||||||
static int stv_vdp2_render_rbg0;
|
static int stv_vdp2_render_rbg0;
|
||||||
int stv_hblank,stv_vblank;
|
int stv_hblank,stv_vblank,stv_odd;
|
||||||
int horz_res,vert_res;
|
int horz_res,vert_res;
|
||||||
|
|
||||||
UINT32* stv_vdp2_cram;
|
UINT32* stv_vdp2_cram;
|
||||||
|
|
||||||
static void stv_vdp2_dynamic_res_change(running_machine *machine);
|
static void stv_vdp2_dynamic_res_change(running_machine *machine);
|
||||||
UINT8 get_vblank(running_machine *machine);
|
UINT8 get_vblank(running_machine *machine);
|
||||||
UINT8 get_hblank(running_machine *machine);
|
UINT8 get_hblank(running_machine *machine);
|
||||||
|
int get_vblank_duration(running_machine *machine);
|
||||||
|
//int get_hblank_duration(running_machine *machine); //<- when we know that...
|
||||||
|
UINT8 get_odd_bit(running_machine *machine);
|
||||||
|
|
||||||
static void refresh_palette_data(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_window_process(int x,int y);
|
||||||
static int stv_vdp2_apply_window_on_layer(rectangle *cliprect);
|
static int stv_vdp2_apply_window_on_layer(rectangle *cliprect);
|
||||||
@ -5277,6 +5285,9 @@ UINT8 get_hblank(running_machine *machine)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//int get_hblank_duration(running_machine *machine)
|
||||||
|
//...
|
||||||
|
|
||||||
UINT8 get_vblank(running_machine *machine)
|
UINT8 get_vblank(running_machine *machine)
|
||||||
{
|
{
|
||||||
static int cur_v;
|
static int cur_v;
|
||||||
@ -5289,6 +5300,43 @@ UINT8 get_vblank(running_machine *machine)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*some vblank lines measurements (according to Charles MacDonald)*/
|
||||||
|
int get_vblank_duration(running_machine *machine)
|
||||||
|
{
|
||||||
|
if(STV_VDP2_HRES & 4)
|
||||||
|
{
|
||||||
|
switch(STV_VDP2_HRES & 1)
|
||||||
|
{
|
||||||
|
case 0: return 45; //31kHz Monitor
|
||||||
|
case 1: return 82; //Hi-Vision Monitor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(STV_VDP2_VRES & 3)
|
||||||
|
{
|
||||||
|
case 0: return 39; //263-224
|
||||||
|
case 1: return 23; //263-240
|
||||||
|
case 2: return 7; //263-256
|
||||||
|
case 3: return 7; //263-256
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT8 get_odd_bit(running_machine *machine)
|
||||||
|
{
|
||||||
|
static int cur_v;
|
||||||
|
cur_v = video_screen_get_vpos(machine->primary_screen);
|
||||||
|
|
||||||
|
if(STV_VDP2_HRES & 4) //exclusive monitor mode makes this bit to be always 1
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if(cur_v % 2)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
READ32_HANDLER ( stv_vdp2_regs_r )
|
READ32_HANDLER ( stv_vdp2_regs_r )
|
||||||
{
|
{
|
||||||
// if (offset!=1) if(LOG_VDP2) logerror ("VDP2: Read from Registers, Offset %04x\n",offset);
|
// if (offset!=1) if(LOG_VDP2) logerror ("VDP2: Read from Registers, Offset %04x\n",offset);
|
||||||
@ -5298,25 +5346,12 @@ READ32_HANDLER ( stv_vdp2_regs_r )
|
|||||||
case 0x4/4:
|
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(space->machine);
|
|
||||||
//if (cur_v > visarea.max_y)
|
|
||||||
stv_vblank = get_vblank(space->machine);
|
stv_vblank = get_vblank(space->machine);
|
||||||
/*ODD bit*/
|
stv_hblank = get_hblank(space->machine);
|
||||||
|
stv_odd = get_odd_bit(space->machine);
|
||||||
|
|
||||||
/*VBLANK HBLANK ODD PAL */
|
/*VBLANK HBLANK ODD PAL */
|
||||||
stv_vdp2_regs[offset] = (stv_vblank<<19) | (stv_hblank<<18) | (1 << 17) | (0 << 16);
|
stv_vdp2_regs[offset] = (stv_vblank<<19) | (stv_hblank<<18) | (stv_odd << 17) | (0 << 16);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x8/4:
|
case 0x8/4:
|
||||||
@ -5400,13 +5435,17 @@ VIDEO_START( stv_vdp2 )
|
|||||||
/* & height / width not yet understood (docs-wise MUST be bigger than normal visible area)*/
|
/* & height / width not yet understood (docs-wise MUST be bigger than normal visible area)*/
|
||||||
static TIMER_CALLBACK( dyn_res_change )
|
static TIMER_CALLBACK( dyn_res_change )
|
||||||
{
|
{
|
||||||
|
UINT8 vblank_period;
|
||||||
rectangle visarea = *video_screen_get_visible_area(machine->primary_screen);
|
rectangle visarea = *video_screen_get_visible_area(machine->primary_screen);
|
||||||
visarea.min_x = 0;
|
visarea.min_x = 0;
|
||||||
visarea.max_x = horz_res-1;
|
visarea.max_x = horz_res-1;
|
||||||
visarea.min_y = 0;
|
visarea.min_y = 0;
|
||||||
visarea.max_y = vert_res-1;
|
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 );
|
vblank_period = get_vblank_duration(machine);
|
||||||
|
// popmessage("%d",vblank_period);
|
||||||
|
// hblank_period = get_hblank_duration(machine->primary_screen);
|
||||||
|
video_screen_configure(machine->primary_screen, horz_res*2, (vert_res+vblank_period), &visarea, video_screen_get_frame_period(machine->primary_screen).attoseconds );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stv_vdp2_dynamic_res_change(running_machine *machine)
|
static void stv_vdp2_dynamic_res_change(running_machine *machine)
|
||||||
|
Loading…
Reference in New Issue
Block a user