From cd6f509841d892d4d195aad6c2a7b05b45f55f78 Mon Sep 17 00:00:00 2001 From: Angelo Salese Date: Mon, 17 Nov 2008 16:56:53 +0000 Subject: [PATCH] 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) --- src/mame/drivers/stv.c | 413 +++++++++++++++++++++++++-------------- src/mame/video/stvvdp1.c | 14 +- 2 files changed, 271 insertions(+), 156 deletions(-) diff --git a/src/mame/drivers/stv.c b/src/mame/drivers/stv.c index 36a95f14ac0..4c36d14ff06 100644 --- a/src/mame/drivers/stv.c +++ b/src/mame/drivers/stv.c @@ -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) diff --git a/src/mame/video/stvvdp1.c b/src/mame/video/stvvdp1.c index b4db77cdd43..69855fdee32 100644 --- a/src/mame/video/stvvdp1.c +++ b/src/mame/video/stvvdp1.c @@ -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 )