ST-V IRQ rewrite and that removes several global hacks/game specific hacks

(SMPC irq bit/introdon irq register hack/pblbeach framebuffer hack plus some more)

(Note: some games have issues with it,but they'll be hopefully fixed on the next couple of updates)
This commit is contained in:
Angelo Salese 2008-11-17 16:56:53 +00:00
parent 230eae0426
commit cd6f509841
2 changed files with 271 additions and 156 deletions

View File

@ -86,6 +86,7 @@ ToDo / Notes:
-To enter into an Advanced Test Mode,keep pressed the Test Button (F2) on the start-up.
(Main issues)
-IRQs: some games have some issues with timing accurate IRQs,check/fix all of them.
-Clean-ups and split the various chips(SCU,SMPC)into their respective files.
-CD block:complete it.
-The Cart-Dev mode hangs even with the -dev bios,I would like to see what it does on the real HW.
@ -153,7 +154,6 @@ ToDo / Notes:
*/
#include "driver.h"
#include "deprecat.h"
#include "machine/eeprom.h"
#include "cpu/sh2/sh2.h"
#include "machine/stvcd.h"
@ -219,6 +219,23 @@ static INT32 scu_size_0, /* Transfer DMA size lv 0*/
scu_size_1, /* lv 1*/
scu_size_2; /* lv 2*/
struct
{
UINT8 vblank_out;
UINT8 vblank_in;
UINT8 hblank_in;
UINT8 timer_0;
UINT8 timer_1;
UINT8 dsp_end;
UINT8 sound_req;
UINT8 smpc;
UINT8 pad;
UINT8 dma_end[3];
UINT8 dma_ill;
UINT8 vdp1_end;
UINT8 abus;
}stv_irq;
static void dma_direct_lv0(running_machine *machine); /*DMA level 0 direct transfer function*/
static void dma_direct_lv1(running_machine *machine); /*DMA level 1 direct transfer function*/
static void dma_direct_lv2(running_machine *machine); /*DMA level 2 direct transfer function*/
@ -230,12 +247,12 @@ static void dma_indirect_lv2(running_machine *machine); /*DMA level 2 indirect t
int minit_boost,sinit_boost;
attotime minit_boost_timeslice, sinit_boost_timeslice;
static int scanline;
//static int scanline;
/*A-Bus IRQ checks,where they could be located these?*/
#define ABUSIRQ(_irq_,_vector_,_mask_) \
if(!(stv_scu[40] & _mask_)) { cpu_set_input_line_and_vector(machine->cpu[0], _irq_, HOLD_LINE , _vector_); }
#define ABUSIRQ(_irq_,_vector_) \
{ cpu_set_input_line_and_vector(device->machine->cpu[0], _irq_, HOLD_LINE , _vector_); }
#if 0
if(stv_scu[42] & 1)//IRQ ACK
{
@ -530,17 +547,17 @@ static void stv_SMPC_w8 (running_machine *machine, int offset, UINT8 data)
SMPC_CONTROL_MODE_PORT_2;
}
/*TODO: probably this is wrong...*/
if(offset == 0x7f)
{
//enable PAD irq & VDP2 external latch for port 1/2
EXLE1 = smpc_ram[0x7f] & 1 ? 1 : 0;
EXLE2 = smpc_ram[0x7f] & 2 ? 1 : 0;
if(EXLE1 || EXLE2)
if(!(stv_scu[40] & 0x0100)) /*Pad irq*/
{
if(LOG_SMPC) logerror ("Interrupt: PAD irq at scanline %04x, Vector 0x48 Level 0x08\n",scanline);
cpu_set_input_line_and_vector(machine->cpu[0], 8, HOLD_LINE , 0x48);
}
{
//if(LOG_SMPC) logerror ("Interrupt: PAD irq at scanline %04x, Vector 0x48 Level 0x08\n",scanline);
cpu_set_input_line_and_vector(machine->cpu[0], 8, (stv_irq.pad) ? HOLD_LINE : CLEAR_LINE, 0x48);
}
}
if (offset == 0x1f)
@ -643,10 +660,10 @@ static void stv_SMPC_w8 (running_machine *machine, int offset, UINT8 data)
smpc_ram[0x5d]=0xff;
// /*This is for RTC,cartridge code and similar stuff...*/
// if(!(stv_scu[40] & 0x0080)) /*System Manager(SMPC) irq*/ /* we can't check this .. breaks controls .. probably issues elsewhere? */
/*System Manager(SMPC) irq*/
{
if(LOG_SMPC) logerror ("Interrupt: System Manager (SMPC) at scanline %04x, Vector 0x47 Level 0x08\n",scanline);
cpu_set_input_line_and_vector(machine->cpu[0], 8, HOLD_LINE , 0x47);
//if(LOG_SMPC) logerror ("Interrupt: System Manager (SMPC) at scanline %04x, Vector 0x47 Level 0x08\n",scanline);
cpu_set_input_line_and_vector(machine->cpu[0], 8, (stv_irq.smpc) ? HOLD_LINE : CLEAR_LINE, 0x47);
}
break;
/* RTC write*/
@ -730,103 +747,6 @@ static WRITE32_HANDLER ( stv_SMPC_w32 )
stv_SMPC_w8(space->machine, offset,writedata);
}
/*
(Preliminary) explaination about this:
VBLANK-OUT is used at the start of the vblank period.It also sets the timer zero
variable to 0.
If the Timer Compare register is zero too,the Timer 0 irq is triggered.
HBLANK-IN is used at the end of each scanline except when in VBLANK-IN/OUT periods.
The timer 0 is also incremented by one at each HBLANK and checked with the value
of the Timer Compare register;if equal,the timer 0 irq is triggered here too.
Notice that the timer 0 compare register can be more than the VBLANK maximum range,in
this case the timer 0 irq is simply never triggered.This is a known Sega Saturn/ST-V "bug".
VBLANK-IN is used at the end of the vblank period.
SCU register[36] is the timer zero compare register.
SCU register[40] is for IRQ masking.
*/
/* to do, update bios idle skips so they work better with this arrangement.. */
static INTERRUPT_GEN( stv_interrupt )
{
scanline = 261-cpu_getiloops(device);
if(scanline == 0)
{
if(!(stv_scu[40] & 2))/*VBLANK-OUT*/
{
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);
}
}
else if(scanline <= 223 && scanline >= 1)/*Correct?*/
{
timer_0++;
timer_1++;
/*TODO: check this...*/
/*Timer 1 handling*/
if((stv_scu[38] & 1))
{
if((!(stv_scu[40] & 0x10)) && (!(stv_scu[38] & 0x80)))
{
if(LOG_IRQ) logerror ("Interrupt: Timer 1 at scanline %04x, Vector 0x44 Level 0x0b\n",scanline);
cpu_set_input_line_and_vector(device, 0xb, HOLD_LINE, 0x44 );
}
else if((!(stv_scu[40] & 0x10)) && (stv_scu[38] & 0x80))
{
if(timer_1 == (stv_scu[36] & 0x1ff))
{
if(LOG_IRQ) logerror ("Interrupt: Timer 1 at scanline %04x, Vector 0x44 Level 0x0b\n",scanline);
cpu_set_input_line_and_vector(device, 0xb, HOLD_LINE, 0x44 );
}
}
}
if(timer_0 == (stv_scu[36] & 0x1ff))
{
if(!(stv_scu[40] & 8))/*Timer 0*/
{
if(LOG_IRQ) logerror ("Interrupt: Timer 0 at scanline %04x, Vector 0x43 Level 0x0c\n",scanline);
cpu_set_input_line_and_vector(device, 0xc, HOLD_LINE, 0x43 );
}
}
/*TODO:use this *at the end* of the draw line.*/
if(!(stv_scu[40] & 4))/*HBLANK-IN*/
{
if(LOG_IRQ) logerror ("Interrupt: HBlank-In at scanline %04x, Vector 0x42 Level 0x0d\n",scanline);
cpu_set_input_line_and_vector(device, 0xd, HOLD_LINE , 0x42);
}
}
else if(scanline == 224)
{
timer_0 = 0;
timer_1 = 0;
if(!(stv_scu[40] & 1))/*VBLANK-IN*/
{
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);
}
if(timer_0 == (stv_scu[36] & 0x1ff))
{
if(!(stv_scu[40] & 8))/*Timer 0*/
{
if(LOG_IRQ) logerror ("Interrupt: Timer 0 at scanline %04x, Vector 0x43 Level 0x0c\n",scanline);
cpu_set_input_line_and_vector(device, 0xc, HOLD_LINE, 0x43 );
}
}
if(!(stv_scu[40] & 0x2000)) /*Sprite draw end irq*/
cpu_set_input_line_and_vector(device, 2, HOLD_LINE , 0x4d);
}
}
/*
I/O overview:
PORT-A 1st player inputs
@ -1164,11 +1084,27 @@ static READ32_HANDLER( stv_scu_r32 )
if(LOG_SCU) logerror( "DSP mem read at %08X\n", stv_scu[34]);
return dsp_ram_addr_r();
}
else if( offset == 41)
else if( offset == 41) /*IRQ reg status read*/
{
logerror("(PC=%08x) IRQ status reg read\n",cpu_get_pc(space->cpu));
/*TODO:for now we're activating everything here,but we need to return the proper active irqs*/
return 0xffffffff;
if(LOG_SCU) logerror("(PC=%08x) IRQ status reg read %08x\n",cpu_get_pc(space->cpu),mem_mask);
stv_scu[41] = (stv_irq.vblank_in & 1)<<0;
stv_scu[41]|= (stv_irq.vblank_out & 1)<<1;
stv_scu[41]|= (stv_irq.hblank_in & 1)<<2;
stv_scu[41]|= (stv_irq.timer_0 & 1)<<3;
stv_scu[41]|= (stv_irq.timer_1 & 1)<<4;
stv_scu[41]|= (stv_irq.dsp_end & 1)<<5;
stv_scu[41]|= (stv_irq.sound_req & 1)<<6;
stv_scu[41]|= (stv_irq.smpc & 1)<<7;
stv_scu[41]|= (stv_irq.pad & 1)<<8;
stv_scu[41]|= (stv_irq.dma_end[0] & 1)<<9;
stv_scu[41]|= (stv_irq.dma_end[1] & 1)<<10;
stv_scu[41]|= (stv_irq.dma_end[2] & 1)<<11;
stv_scu[41]|= (stv_irq.dma_ill & 1)<<12;
stv_scu[41]|= (stv_irq.vdp1_end & 1)<<13;
stv_scu[41]|= (stv_irq.abus & 1)<<15;
return stv_scu[41] ^ 0xffffffff;
}
else if( offset == 50 )
{
@ -1386,7 +1322,22 @@ static WRITE32_HANDLER( stv_scu_w32 )
case 40:
/*An interrupt is masked when his specific bit is 1.*/
/*Are bit 16-bit 31 for External A-Bus irq mask like the status register?*/
/*What is 0x00000080 setting?Is it valid?*/
stv_irq.vblank_in = (((stv_scu[40] & 0x0001)>>0) ^ 1);
stv_irq.vblank_out = (((stv_scu[40] & 0x0002)>>1) ^ 1);
stv_irq.hblank_in = (((stv_scu[40] & 0x0004)>>2) ^ 1);
stv_irq.timer_0 = (((stv_scu[40] & 0x0008)>>3) ^ 1);
stv_irq.timer_1 = (((stv_scu[40] & 0x0010)>>4) ^ 1);
stv_irq.dsp_end = (((stv_scu[40] & 0x0020)>>5) ^ 1);
stv_irq.sound_req = (((stv_scu[40] & 0x0040)>>6) ^ 1);
stv_irq.smpc = (((stv_scu[40] & 0x0080)>>7)); //NOTE: SCU bug
stv_irq.pad = (((stv_scu[40] & 0x0100)>>8) ^ 1);
stv_irq.dma_end[0] = (((stv_scu[40] & 0x0200)>>9) ^ 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_ill = (((stv_scu[40] & 0x1000)>>12) ^ 1);
stv_irq.vdp1_end = (((stv_scu[40] & 0x2000)>>13) ^ 1);
stv_irq.abus = (((stv_scu[40] & 0x8000)>>15) ^ 1);
/*Take out the common settings to keep logging quiet.*/
if(stv_scu[40] != 0xfffffffe &&
@ -1414,9 +1365,27 @@ static WRITE32_HANDLER( stv_scu_w32 )
stv_scu[offset] & 0x0001 ? 1 : 0);/*VBlank-IN*/
}
break;
/*Interrupt Control reg Set*/
case 41:
/*This is r/w by introdon...*/
if(LOG_SCU) logerror("IRQ status reg set:%08x\n",stv_scu[41]);
if(LOG_SCU) logerror("IRQ status reg set:%08x %08x\n",stv_scu[41],mem_mask);
stv_irq.vblank_in = ((stv_scu[41] & 0x0001)>>0);
stv_irq.vblank_out = ((stv_scu[41] & 0x0002)>>1);
stv_irq.hblank_in = ((stv_scu[41] & 0x0004)>>2);
stv_irq.timer_0 = ((stv_scu[41] & 0x0008)>>3);
stv_irq.timer_1 = ((stv_scu[41] & 0x0010)>>4);
stv_irq.dsp_end = ((stv_scu[41] & 0x0020)>>5);
stv_irq.sound_req = ((stv_scu[41] & 0x0040)>>6);
stv_irq.smpc = ((stv_scu[41] & 0x0080)>>7);
stv_irq.pad = ((stv_scu[41] & 0x0100)>>8);
stv_irq.dma_end[0] = ((stv_scu[41] & 0x0200)>>9);
stv_irq.dma_end[1] = ((stv_scu[41] & 0x0400)>>10);
stv_irq.dma_end[2] = ((stv_scu[41] & 0x0800)>>11);
stv_irq.dma_ill = ((stv_scu[41] & 0x1000)>>12);
stv_irq.vdp1_end = ((stv_scu[41] & 0x2000)>>13);
stv_irq.abus = ((stv_scu[41] & 0x8000)>>15);
break;
case 42: if(LOG_SCU) logerror("A-Bus IRQ ACK %08x\n",stv_scu[42]); break;
case 49: if(LOG_SCU) logerror("SCU SDRAM set: %02x\n",stv_scu[49]); break;
@ -1424,6 +1393,30 @@ static WRITE32_HANDLER( stv_scu_w32 )
}
}
/*Lv 0 DMA end irq*/
static TIMER_CALLBACK( dma_lv0_ended )
{
cpu_set_input_line_and_vector(machine->cpu[0], 5, (stv_irq.dma_end[0]) ? HOLD_LINE : CLEAR_LINE, 0x4b);
D0MV_0;
}
/*Lv 1 DMA end irq*/
static TIMER_CALLBACK( dma_lv1_ended )
{
cpu_set_input_line_and_vector(machine->cpu[0], 6, (stv_irq.dma_end[1]) ? HOLD_LINE : CLEAR_LINE, 0x4a);
D1MV_0;
}
/*Lv 2 DMA end irq*/
static TIMER_CALLBACK( dma_lv2_ended )
{
cpu_set_input_line_and_vector(machine->cpu[0], 6, (stv_irq.dma_end[2]) ? HOLD_LINE : CLEAR_LINE, 0x49);
D2MV_0;
}
static void dma_direct_lv0(running_machine *machine)
{
static UINT32 tmp_src,tmp_dst,tmp_size;
@ -1521,8 +1514,9 @@ static void dma_direct_lv0(running_machine *machine)
if(!(DWUP(0))) scu_dst_0 = tmp_dst;
if(LOG_SCU) logerror("DMA transfer END\n");
if(!(stv_scu[40] & 0x800))/*Lv 0 DMA end irq*/
cpu_set_input_line_and_vector(machine->cpu[0], 5, HOLD_LINE , 0x4b);
/*TODO: timing of this*/
timer_set(ATTOTIME_IN_USEC(300), NULL, 0, dma_lv0_ended);
if(scu_add_tmp & 0x80000000)
{
@ -1530,8 +1524,6 @@ static void dma_direct_lv0(running_machine *machine)
scu_src_add_0 = (scu_add_tmp & 0x00ff) >> 0;
scu_add_tmp^=0x80000000;
}
D0MV_0;
}
static void dma_direct_lv1(running_machine *machine)
@ -1624,8 +1616,8 @@ static void dma_direct_lv1(running_machine *machine)
if(!(DWUP(1))) scu_dst_1 = tmp_dst;
if(LOG_SCU) logerror("DMA transfer END\n");
if(!(stv_scu[40] & 0x400))/*Lv 1 DMA end irq*/
cpu_set_input_line_and_vector(machine->cpu[0], 6, HOLD_LINE , 0x4a);
timer_set(ATTOTIME_IN_USEC(300), NULL, 0, dma_lv1_ended);
if(scu_add_tmp & 0x80000000)
{
@ -1633,8 +1625,6 @@ static void dma_direct_lv1(running_machine *machine)
scu_src_add_1 = (scu_add_tmp & 0x00ff) >> 0;
scu_add_tmp^=0x80000000;
}
D1MV_0;
}
static void dma_direct_lv2(running_machine *machine)
@ -1727,8 +1717,8 @@ static void dma_direct_lv2(running_machine *machine)
if(!(DWUP(2))) scu_dst_2 = tmp_dst;
if(LOG_SCU) logerror("DMA transfer END\n");
if(!(stv_scu[40] & 0x200))/*Lv 2 DMA end irq*/
cpu_set_input_line_and_vector(machine->cpu[0], 6, HOLD_LINE , 0x49);
timer_set(ATTOTIME_IN_USEC(300), NULL, 0, dma_lv2_ended);
if(scu_add_tmp & 0x80000000)
{
@ -1736,8 +1726,6 @@ static void dma_direct_lv2(running_machine *machine)
scu_src_add_2 = (scu_add_tmp & 0x00ff) >> 0;
scu_add_tmp^=0x80000000;
}
D2MV_0;
}
static void dma_indirect_lv0(running_machine *machine)
@ -1805,10 +1793,7 @@ static void dma_indirect_lv0(running_machine *machine)
}while(job_done == 0);
if(!(stv_scu[40] & 0x800))/*Lv 0 DMA end irq*/
cpu_set_input_line_and_vector(machine->cpu[0], 5, HOLD_LINE , 0x4b);
D0MV_0;
timer_set(ATTOTIME_IN_USEC(300), NULL, 0, dma_lv0_ended);
}
static void dma_indirect_lv1(running_machine *machine)
@ -1877,10 +1862,7 @@ static void dma_indirect_lv1(running_machine *machine)
}while(job_done == 0);
if(!(stv_scu[40] & 0x400))/*Lv 1 DMA end irq*/
cpu_set_input_line_and_vector(machine->cpu[0], 6, HOLD_LINE , 0x4a);
D1MV_0;
timer_set(ATTOTIME_IN_USEC(300), NULL, 0, dma_lv1_ended);
}
static void dma_indirect_lv2(running_machine *machine)
@ -1948,10 +1930,7 @@ static void dma_indirect_lv2(running_machine *machine)
}while(job_done == 0);
if(!(stv_scu[40] & 0x200))/*Lv 2 DMA end irq*/
cpu_set_input_line_and_vector(machine->cpu[0], 6, HOLD_LINE , 0x49);
D2MV_0;
timer_set(ATTOTIME_IN_USEC(300), NULL, 0, dma_lv2_ended);
}
@ -2025,10 +2004,6 @@ static ADDRESS_MAP_START( stv_mem, ADDRESS_SPACE_PROGRAM, 32 )
//AM_RANGE(0x05a80000, 0x05afffff) AM_READ(stv_sh2_random_r)
AM_RANGE(0x05b00000, 0x05b00fff) AM_READWRITE(stv_scsp_regs_r32, stv_scsp_regs_w32)
/* VDP1 */
/*0x05c00000-0x05c7ffff VRAM*/
/*0x05c80000-0x05c9ffff Frame Buffer 0*/
/*0x05ca0000-0x05cbffff Frame Buffer 1*/
/*0x05d00000-0x05d7ffff VDP1 Regs */
AM_RANGE(0x05c00000, 0x05c7ffff) AM_READWRITE(stv_vdp1_vram_r, stv_vdp1_vram_w)
AM_RANGE(0x05c80000, 0x05cbffff) AM_READWRITE(stv_vdp1_framebuffer0_r, stv_vdp1_framebuffer0_w)
AM_RANGE(0x05d00000, 0x05d0001f) AM_READWRITE(stv_vdp1_regs_r, stv_vdp1_regs_w)
@ -2538,7 +2513,7 @@ static MACHINE_START( stv )
state_save_register_global(en_68k);
state_save_register_global(timer_0);
state_save_register_global(timer_1);
state_save_register_global(scanline);
// state_save_register_global(scanline);
state_save_register_global(IOSEL1);
state_save_register_global(IOSEL2);
state_save_register_global(EXLE1);
@ -2554,6 +2529,145 @@ static MACHINE_START( stv )
add_exit_callback(machine, stvcd_exit);
}
/*
(Preliminary) explaination about this:
VBLANK-OUT is used at the start of the vblank period.It also sets the timer zero
variable to 0.
If the Timer Compare register is zero too,the Timer 0 irq is triggered.
HBLANK-IN is used at the end of each scanline except when in VBLANK-IN/OUT periods.
The timer 0 is also incremented by one at each HBLANK and checked with the value
of the Timer Compare register;if equal,the timer 0 irq is triggered here too.
Notice that the timer 0 compare register can be more than the VBLANK maximum range,in
this case the timer 0 irq is simply never triggered.This is a known Sega Saturn/ST-V "bug".
VBLANK-IN is used at the end of the vblank period.
SCU register[36] is the timer zero compare register.
SCU register[40] is for IRQ masking.
*/
/* to do, update bios idle skips so they work better with this arrangement.. */
static emu_timer *vblank_in_timer,*scan_timer,*t1_timer;
static int h_sync,v_sync;
static int cur_scan;
#define VBLANK_OUT_IRQ \
timer_0 = 0; \
{ \
/*if(LOG_IRQ) logerror ("Interrupt: VBlank-OUT Vector 0x41 Level 0x0e\n");*/ \
cpu_set_input_line_and_vector(device->machine->cpu[0], 0xe, (stv_irq.vblank_out) ? HOLD_LINE : CLEAR_LINE , 0x41); \
} \
#define VBLANK_IN_IRQ \
{ \
/*if(LOG_IRQ) logerror ("Interrupt: VBlank IN Vector 0x40 Level 0x0f\n");*/ \
cpu_set_input_line_and_vector(machine->cpu[0], 0xf, (stv_irq.vblank_in) ? HOLD_LINE : CLEAR_LINE , 0x40); \
} \
#define HBLANK_IN_IRQ \
timer_1 = stv_scu[37] & 0x1ff; \
{ \
/*if(LOG_IRQ) logerror ("Interrupt: HBlank-In at scanline %04x, Vector 0x42 Level 0x0d\n",scanline);*/ \
cpu_set_input_line_and_vector(machine->cpu[0], 0xd, (stv_irq.hblank_in) ? HOLD_LINE : CLEAR_LINE, 0x42); \
} \
#define TIMER_0_IRQ \
if(timer_0 == (stv_scu[36] & 0x3ff)) \
{ \
/*if(LOG_IRQ) logerror ("Interrupt: Timer 0 at scanline %04x, Vector 0x43 Level 0x0c\n",scanline);*/ \
cpu_set_input_line_and_vector(machine->cpu[0], 0xc, (stv_irq.timer_0) ? HOLD_LINE : CLEAR_LINE, 0x43 ); \
} \
#define TIMER_1_IRQ \
if((stv_scu[38] & 1)) \
{ \
if(!(stv_scu[38] & 0x80)) \
{ \
/*if(LOG_IRQ) logerror ("Interrupt: Timer 1 at point %04x, Vector 0x44 Level 0x0b\n",point);*/ \
cpu_set_input_line_and_vector(machine->cpu[0], 0xb, (stv_irq.timer_1) ? HOLD_LINE : CLEAR_LINE, 0x44 ); \
} \
else \
{ \
if((timer_0) == (stv_scu[36] & 0x3ff)) \
{ \
/*if(LOG_IRQ) logerror ("Interrupt: Timer 1 at point %04x, Vector 0x44 Level 0x0b\n",point);*/ \
cpu_set_input_line_and_vector(machine->cpu[0], 0xb, (stv_irq.timer_1) ? HOLD_LINE : CLEAR_LINE, 0x44 ); \
} \
} \
} \
#define VDP1_IRQ \
{ \
cpu_set_input_line_and_vector(machine->cpu[0], 2, (stv_irq.vdp1_end) ? HOLD_LINE : CLEAR_LINE, 0x4d); \
} \
static TIMER_CALLBACK( hblank_in_irq )
{
int scanline = param;
// h = video_screen_get_height(machine->primary_screen);
// w = video_screen_get_width(machine->primary_screen);
TIMER_0_IRQ;
HBLANK_IN_IRQ;
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);
/*set the first Timer-1 event*/
cur_scan = scanline+1;
timer_adjust_oneshot(t1_timer, video_screen_get_time_until_pos(machine->primary_screen, scanline+1, 0), 0);
}
timer_0++;
}
static TIMER_CALLBACK( timer1_irq )
{
int cur_point = param;
TIMER_1_IRQ;
if((cur_point+1) < h_sync)
{
timer_adjust_oneshot(t1_timer, video_screen_get_time_until_pos(machine->primary_screen, cur_scan, cur_point+1), cur_point+1);
}
if(timer_1 > 0) timer_1--;
}
static TIMER_CALLBACK( vdp1_irq )
{
VDP1_IRQ;
}
static TIMER_CALLBACK( vblank_in_irq )
{
VBLANK_IN_IRQ;
}
/*V-Blank-OUT event*/
static INTERRUPT_GEN( stv_interrupt )
{
// scanline = 0;
h_sync = video_screen_get_height(device->machine->primary_screen)/2;//horz
v_sync = video_screen_get_width(device->machine->primary_screen)-2;//vert
VBLANK_OUT_IRQ;
/*Next V-Blank-IN event*/
timer_adjust_oneshot(vblank_in_timer,video_screen_get_time_until_pos(device->machine->primary_screen, 0, 0), 0);
/*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);
/*TODO: timing of this one (related to the VDP1 speed)*/
/* (NOTE: value shouldn't be at h_sync/v_sync position (will break shienryu))*/
timer_set(video_screen_get_time_until_pos(device->machine->primary_screen,0,0), NULL, 0, vdp1_irq);
}
static MACHINE_RESET( stv )
{
// don't let the slave cpu and the 68k go anywhere
@ -2575,6 +2689,13 @@ static MACHINE_RESET( stv )
cpu_set_clock(machine->cpu[2], MASTER_CLOCK_320/5);
stvcd_reset(machine);
/* set the first scanline 0 timer to go off */
scan_timer = timer_alloc(hblank_in_irq, NULL);
t1_timer = timer_alloc(timer1_irq,NULL);
vblank_in_timer = timer_alloc(vblank_in_irq,NULL);
timer_adjust_oneshot(vblank_in_timer,video_screen_get_time_until_pos(machine->primary_screen, 0, 0), 0);
timer_adjust_oneshot(scan_timer, video_screen_get_time_until_pos(machine->primary_screen, 224, 352), 0);
}
@ -2583,7 +2704,7 @@ static MACHINE_DRIVER_START( stv )
/* basic machine hardware */
MDRV_CPU_ADD("main", SH2, MASTER_CLOCK_352/2) // 28.6364 MHz
MDRV_CPU_PROGRAM_MAP(stv_mem, 0)
MDRV_CPU_VBLANK_INT_HACK(stv_interrupt,264)/*264 lines,224 display lines*/
MDRV_CPU_VBLANK_INT("main",stv_interrupt)
MDRV_CPU_CONFIG(sh2_conf_master)
MDRV_CPU_ADD("slave", SH2, MASTER_CLOCK_352/2) // 28.6364 MHz
@ -2598,7 +2719,7 @@ static MACHINE_DRIVER_START( stv )
MDRV_NVRAM_HANDLER(stv) /* Actually 93c45 */
/* video hardware */
MDRV_VIDEO_ATTRIBUTES(VIDEO_UPDATE_AFTER_VBLANK )
MDRV_VIDEO_ATTRIBUTES(VIDEO_UPDATE_AFTER_VBLANK)
MDRV_SCREEN_ADD("main", RASTER)
MDRV_SCREEN_REFRESH_RATE(60)

View File

@ -301,10 +301,10 @@ WRITE32_HANDLER( stv_vdp1_regs_w )
}
/* needed by pblbeach, it doesn't clear local coordinates in its sprite list...*/
if ( !strcmp(space->machine->gamedrv->name, "pblbeach") )
{
stvvdp1_local_x = stvvdp1_local_y = 0;
}
//if ( !strcmp(space->machine->gamedrv->name, "pblbeach") )
//{
// stvvdp1_local_x = stvvdp1_local_y = 0;
//}
}
}
else if ( offset == 1 )
@ -315,12 +315,6 @@ WRITE32_HANDLER( stv_vdp1_regs_w )
{
if ( vdp1_sprite_log ) logerror( "VDP1: Access to register PTMR = %1X\n", STV_VDP1_PTMR );
stv_vdp1_process_list( );
if(!(stv_scu[40] & 0x2000)) /*Sprite draw end irq*/
{
logerror( "Interrupt: Sprite draw end, Vector 0x4d, Level 0x02\n" );
cpu_set_input_line_and_vector(space->machine->cpu[0], 2, HOLD_LINE , 0x4d);
}
}
}
else if ( ACCESSING_BITS_0_15 )