diff options
Diffstat (limited to 'src/mame/machine/saturn.cpp')
-rw-r--r-- | src/mame/machine/saturn.cpp | 628 |
1 files changed, 6 insertions, 622 deletions
diff --git a/src/mame/machine/saturn.cpp b/src/mame/machine/saturn.cpp index 7907f5bfd21..fcea8b20e19 100644 --- a/src/mame/machine/saturn.cpp +++ b/src/mame/machine/saturn.cpp @@ -54,504 +54,6 @@ #define LOG_IRQ 0 #define LOG_IOGA 0 -/**************************************************************************************/ - -/* - -SCU Handling - -*/ - -/********************************************************************************** -SCU Register Table -offset,relative address -Registers are in long words. -=================================================================================== -0 0000 Level 0 DMA Set Register -1 0004 -2 0008 -3 000c -4 0010 -5 0014 -6 0018 -7 001c -8 0020 Level 1 DMA Set Register -9 0024 -10 0028 -11 002c -12 0030 -13 0034 -14 0038 -15 003c -16 0040 Level 2 DMA Set Register -17 0044 -18 0048 -19 004c -20 0050 -21 0054 -22 0058 -23 005c -24 0060 DMA Forced Stop -25 0064 -26 0068 -27 006c -28 0070 <Free> -29 0074 -30 0078 -31 007c DMA Status Register -32 0080 DSP Program Control Port -33 0084 DSP Program RAM Data Port -34 0088 DSP Data RAM Address Port -35 008c DSP Data RAM Data Port -36 0090 Timer 0 Compare Register -37 0094 Timer 1 Set Data Register -38 0098 Timer 1 Mode Register -39 009c <Free> -40 00a0 Interrupt Mask Register -41 00a4 Interrupt Status Register -42 00a8 A-Bus Interrupt Acknowledge -43 00ac <Free> -44 00b0 A-Bus Set Register -45 00b4 -46 00b8 A-Bus Refresh Register -47 00bc <Free> -48 00c0 -49 00c4 SCU SDRAM Select Register -50 00c8 SCU Version Register -51 00cc <Free> -52 00cf -=================================================================================== -DMA Status Register(32-bit): -xxxx xxxx x--- xx-- xx-- xx-- xx-- xx-- UNUSED ----- ---- -x-- ---- ---- ---- ---- ---- DMA DSP-Bus access ----- ---- --x- ---- ---- ---- ---- ---- DMA B-Bus access ----- ---- ---x ---- ---- ---- ---- ---- DMA A-Bus access ----- ---- ---- --x- ---- ---- ---- ---- DMA lv 1 interrupt ----- ---- ---- ---x ---- ---- ---- ---- DMA lv 0 interrupt ----- ---- ---- ---- --x- ---- ---- ---- DMA lv 2 in stand-by ----- ---- ---- ---- ---x ---- ---- ---- DMA lv 2 in operation ----- ---- ---- ---- ---- --x- ---- ---- DMA lv 1 in stand-by ----- ---- ---- ---- ---- ---x ---- ---- DMA lv 1 in operation ----- ---- ---- ---- ---- ---- --x- ---- DMA lv 0 in stand-by ----- ---- ---- ---- ---- ---- ---x ---- DMA lv 0 in operation ----- ---- ---- ---- ---- ---- ---- --x- DSP side DMA in stand-by ----- ---- ---- ---- ---- ---- ---- ---x DSP side DMA in operation - -**********************************************************************************/ -/* -DMA TODO: --Remove CD transfer DMA hack (tied with CD block bug(s)?) --Add timings(but how fast are each DMA?). --Add level priority & DMA status register. -*/ - -#define DIRECT_MODE(_lv_) (!(m_scu_regs[5+(_lv_*8)] & 0x01000000)) -#define INDIRECT_MODE(_lv_) (m_scu_regs[5+(_lv_*8)] & 0x01000000) -#define DRUP(_lv_) (m_scu_regs[5+(_lv_*8)] & 0x00010000) -#define DWUP(_lv_) (m_scu_regs[5+(_lv_*8)] & 0x00000100) - -/*These macros sets the various DMA status flags.*/ -#define DnMV_1(_ch_) m_scu.status|=(0x10 << 4 * _ch_) -#define DnMV_0(_ch_) m_scu.status&=~(0x10 << 4 * _ch_) - -/*For area checking*/ -#define BIOS_BUS(var) (var & 0x07f00000) == 0 -#define ABUS(_lv_) ((m_scu.src[_lv_] & 0x07000000) >= 0x02000000) && ((m_scu.src[_lv_] & 0x07000000) <= 0x04000000) -#define BBUS(_lv_) ((scu_##_lv_ & 0x07ffffff) >= 0x05a00000) && ((scu_##_lv_ & 0x07ffffff) <= 0x05ffffff) -#define VDP1_REGS(_lv_) ((scu_##_lv_ & 0x07ffffff) >= 0x05d00000) && ((scu_##_lv_ & 0x07ffffff) <= 0x05dfffff) -#define VDP2(_lv_) ((scu_##_lv_ & 0x07ffffff) >= 0x05e00000) && ((scu_##_lv_ & 0x07ffffff) <= 0x05fdffff) -#define WORK_RAM_L(_lv_) ((scu_##_lv_ & 0x07ffffff) >= 0x00200000) && ((scu_##_lv_ & 0x07ffffff) <= 0x002fffff) -#define WORK_RAM_H(var) (var & 0x07000000) == 0x06000000 -#define SOUND_RAM(_lv_) ((scu_##_lv_ & 0x07ffffff) >= 0x05a00000) && ((scu_##_lv_ & 0x07ffffff) <= 0x05afffff) - -void saturn_state::scu_do_transfer(uint8_t event) -{ - address_space &space = machine().device("maincpu")->memory().space(AS_PROGRAM); - int i; - - for(i=0;i<3;i++) - { - if(m_scu.enable_mask[i] && m_scu.start_factor[i] == event) - { - if(DIRECT_MODE(i)) { scu_dma_direct(space,i); } - else { scu_dma_indirect(space,i); } - } - } -} - -/* test pending irqs */ -void saturn_state::scu_test_pending_irq() -{ - int i; - const int irq_level[32] = { 0xf, 0xe, 0xd, 0xc, - 0xb, 0xa, 0x9, 0x8, - 0x8, 0x6, 0x6, 0x5, - 0x3, 0x2, -1, -1, - 0x7, 0x7, 0x7, 0x7, - 0x4, 0x4, 0x4, 0x4, - 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1 }; - - for(i=0;i<32;i++) - { - if((!(m_scu.ism & 1 << i)) && (m_scu.ist & 1 << i)) - { - if(irq_level[i] != -1) /* TODO: cheap check for undefined irqs */ - { - m_maincpu->set_input_line_and_vector(irq_level[i], HOLD_LINE, 0x40 + i); - m_scu.ist &= ~(1 << i); - return; /* avoid spurious irqs, correct? */ - } - } - } -} - -READ32_MEMBER(saturn_state::saturn_scu_r) -{ - uint32_t res; - - /*TODO: write only registers must return 0 or open bus */ - switch(offset) - { - case 0x5c/4: - // Super Major League and Shin Megami Tensei - Akuma Zensho reads from there (undocumented), DMA status mirror? - if(LOG_SCU && !machine().side_effect_disabled()) logerror("(PC=%08x) DMA status reg read\n",space.device().safe_pc()); - res = m_scu.status; - break; - case 0x7c/4: - if(LOG_SCU && !machine().side_effect_disabled()) logerror("(PC=%08x) DMA status reg read\n",space.device().safe_pc()); - res = m_scu.status; - break; - case 0x80/4: - res = m_scudsp->program_control_r(space, 0, mem_mask); - break; - case 0x8c/4: - if(LOG_SCU && !machine().side_effect_disabled()) logerror( "DSP mem read at %08X\n", m_scu_regs[34]); - res = m_scudsp->ram_address_r(space, 0, mem_mask); - break; - case 0xa0/4: - if(LOG_SCU && !machine().side_effect_disabled()) logerror("(PC=%08x) IRQ mask reg read %08x MASK=%08x\n",space.device().safe_pc(),mem_mask,m_scu_regs[0xa0/4]); - res = m_scu.ism; - break; - case 0xa4/4: - if(LOG_SCU && !machine().side_effect_disabled()) logerror("(PC=%08x) IRQ status reg read MASK=%08x IST=%08x | ISM=%08x\n",space.device().safe_pc(),mem_mask,m_scu.ist,m_scu.ism); - /* TODO: Bug! trips an HW fault. Basically, it tries to read the IST bit 1 with that irq enabled. - Densetsu no Ogre Battle doesn't like this, so it needs investigation ... - */ -// res = m_scu.ist | ~m_scu.ism; - res = m_scu.ist; - break; - case 0xc8/4: - if(LOG_SCU && !machine().side_effect_disabled()) logerror("(PC=%08x) SCU version reg read\n",space.device().safe_pc()); - res = 0x00000004;/*SCU Version 4, OK? */ - break; - default: - if(LOG_SCU && !machine().side_effect_disabled()) logerror("(PC=%08x) SCU reg read at %d = %08x\n",space.device().safe_pc(),offset,m_scu_regs[offset]); - res = m_scu_regs[offset]; - break; - } - - return res; -} - -#define DMA_CH ((offset & 0x18) / 8) - -WRITE32_MEMBER(saturn_state::saturn_scu_w) -{ - COMBINE_DATA(&m_scu_regs[offset]); - - switch(offset) - { - /*LV 0 DMA*/ - case 0x00/4: case 0x20/4: case 0x40/4: m_scu.src[DMA_CH] = ((m_scu_regs[offset] & 0x07ffffff) >> 0); break; - case 0x04/4: case 0x24/4: case 0x44/4: m_scu.dst[DMA_CH] = ((m_scu_regs[offset] & 0x07ffffff) >> 0); break; - case 0x08/4: case 0x28/4: case 0x48/4: m_scu.size[DMA_CH] = ((m_scu_regs[offset] & ((offset == 2) ? 0x000fffff : 0xfff)) >> 0); break; - case 0x0c/4: case 0x2c/4: case 0x4c/4: - m_scu.src_add[DMA_CH] = (m_scu_regs[offset] & 0x100) ? 4 : 0; - m_scu.dst_add[DMA_CH] = 1 << (m_scu_regs[offset] & 7); - if(m_scu.dst_add[DMA_CH] == 1) { m_scu.dst_add[DMA_CH] = 0; } - break; - case 0x10/4: case 0x30/4: case 0x50/4: - m_scu.enable_mask[DMA_CH] = (data & 0x100) >> 8; - if(m_scu.enable_mask[DMA_CH] && m_scu.start_factor[DMA_CH] == 7 && m_scu_regs[offset] & 1) - { - if(DIRECT_MODE(DMA_CH)) { scu_dma_direct(space,DMA_CH); } - else { scu_dma_indirect(space,DMA_CH); } - m_scu_regs[offset]&=~1;//disable starting bit. - } - break; - case 0x14/4: case 0x34/4: case 0x54/4: - if(INDIRECT_MODE(DMA_CH)) - { - //if(LOG_SCU) logerror("Indirect Mode DMA lv %d set\n",DMA_CH); - if(!DWUP(DMA_CH)) m_scu.index[DMA_CH] = m_scu.dst[DMA_CH]; - } - - m_scu.start_factor[DMA_CH] = m_scu_regs[offset] & 7; - break; - - case 0x60/4: - if(LOG_SCU) logerror("DMA Forced Stop Register set = %02x\n",m_scu_regs[24]); - break; - case 0x7c/4: if(LOG_SCU) logerror("Warning: DMA status WRITE! Offset %02x(%d)\n",offset*4,offset); break; - /*DSP section*/ - case 0x80/4: - m_scudsp->program_control_w(space, 0, m_scu_regs[offset], mem_mask); - if(LOG_SCU) logerror("SCU DSP: Program Control Port Access %08x\n",data); - break; - case 0x84/4: - m_scudsp->program_w(space, 0, m_scu_regs[offset], mem_mask); - if(LOG_SCU) logerror("SCU DSP: Program RAM Data Port Access %08x\n",data); - break; - case 0x88/4: - m_scudsp->ram_address_control_w(space, 0,m_scu_regs[offset], mem_mask); - if(LOG_SCU) logerror("SCU DSP: Data RAM Address Port Access %08x\n",data); - break; - case 0x8c/4: - m_scudsp->ram_address_w(space, 0, m_scu_regs[offset], mem_mask); - if(LOG_SCU) logerror("SCU DSP: Data RAM Data Port Access %08x\n",data); - break; - case 0x90/4: /*if(LOG_SCU) logerror("timer 0 compare data = %03x\n",m_scu_regs[36]);*/ break; - case 0x94/4: /*if(LOG_SCU) logerror("timer 1 set data = %08x\n",m_scu_regs[37]);*/ break; - case 0x98/4: /*if(LOG_SCU) logerror("timer 1 mode data = %08x\n",m_scu_regs[38]);*/ break; - case 0xa0/4: /* IRQ mask */ - m_scu.ism = m_scu_regs[0xa0/4]; - scu_test_pending_irq(); - break; - case 0xa4/4: /* IRQ control */ - if(LOG_SCU) logerror("PC=%08x IRQ status reg set:%08x %08x\n",space.device().safe_pc(),m_scu_regs[41],mem_mask); - m_scu.ist &= m_scu_regs[offset]; - scu_test_pending_irq(); - break; - case 0xa8/4: - /* This sends an irq signal to the extra devices connected to the A-Bus, not really needed for now. */ - //if(LOG_SCU) logerror("A-Bus IRQ ACK %08x\n",m_scu_regs[42]); - break; - case 0xc4/4: if(LOG_SCU) logerror("SCU SDRAM set: %02x\n",m_scu_regs[49]); break; - default: if(LOG_SCU) logerror("Warning: unused SCU reg set %d = %08x\n",offset,data); - } -} - -/*Lv 0 DMA end irq*/ -TIMER_CALLBACK_MEMBER(saturn_state::dma_lv0_ended ) -{ - if(!(m_scu.ism & IRQ_DMALV0)) - m_maincpu->set_input_line_and_vector(5, HOLD_LINE, 0x4b); - else - m_scu.ist |= (IRQ_DMALV0); - - DnMV_0(0); - machine().scheduler().synchronize(); // force resync -} - -/*Lv 1 DMA end irq*/ -TIMER_CALLBACK_MEMBER(saturn_state::dma_lv1_ended) -{ - if(!(m_scu.ism & IRQ_DMALV1)) - m_maincpu->set_input_line_and_vector(6, HOLD_LINE, 0x4a); - else - m_scu.ist |= (IRQ_DMALV1); - - DnMV_0(1); - machine().scheduler().synchronize(); // force resync -} - -/*Lv 2 DMA end irq*/ -TIMER_CALLBACK_MEMBER(saturn_state::dma_lv2_ended) -{ - if(!(m_scu.ism & IRQ_DMALV2)) - m_maincpu->set_input_line_and_vector(6, HOLD_LINE, 0x49); - else - m_scu.ist |= (IRQ_DMALV2); - - DnMV_0(2); - machine().scheduler().synchronize(); // force resync -} - -void saturn_state::scu_single_transfer(address_space &space, uint32_t src, uint32_t dst,uint8_t *src_shift) -{ - uint32_t src_data; - - if(src & 1) - { - /* Road Blaster does a work ram h to color ram with offsetted source address, do some data rotation */ - src_data = ((space.read_dword(src & 0x07fffffc) & 0x00ffffff)<<8); - src_data |= ((space.read_dword((src & 0x07fffffc)+4) & 0xff000000) >> 24); - src_data >>= (*src_shift)*16; - } - else - src_data = space.read_dword(src & 0x07fffffc) >> (*src_shift)*16; - - space.write_word(dst,src_data); - - *src_shift ^= 1; -} - -void saturn_state::scu_dma_direct(address_space &space, uint8_t dma_ch) -{ - uint32_t tmp_src,tmp_dst,total_size; - uint8_t cd_transfer_flag; - - if(m_scu.src_add[dma_ch] == 0 || (m_scu.dst_add[dma_ch] != 2 && m_scu.dst_add[dma_ch] != 4)) - { - if(LOG_SCU) printf("DMA lv %d transfer START\n" - "Start %08x End %08x Size %04x\n",dma_ch,m_scu.src[dma_ch],m_scu.dst[dma_ch],m_scu.size[dma_ch]); - if(LOG_SCU) printf("Start Add %04x Destination Add %04x\n",m_scu.src_add[dma_ch],m_scu.dst_add[dma_ch]); - } - - /* Game Basic and World Cup 98 trips this, according to the docs the SCU can't transfer from BIOS area (can't communicate from/to that bus) */ - if(BIOS_BUS(m_scu.src[dma_ch])) - { - popmessage("Warning: SCU transfer from BIOS area, contact MAMEdev"); - if(!(m_scu.ism & IRQ_DMAILL)) - m_maincpu->set_input_line_and_vector(3, HOLD_LINE, 0x4c); - else - m_scu.ist |= (IRQ_DMAILL); - return; - } - - DnMV_1(dma_ch); - - /* max size */ - if(m_scu.size[dma_ch] == 0) { m_scu.size[dma_ch] = (dma_ch == 0) ? 0x00100000 : 0x1000; } - - tmp_src = tmp_dst = 0; - - total_size = m_scu.size[dma_ch]; - if(!(DRUP(dma_ch))) tmp_src = m_scu.src[dma_ch]; - if(!(DWUP(dma_ch))) tmp_dst = m_scu.dst[dma_ch]; - - cd_transfer_flag = m_scu.src_add[dma_ch] == 0 && m_scu.src[dma_ch] == 0x05818000; - - /* TODO: Many games directly accesses CD-ROM register 0x05818000, it must be a dword access with current implementation otherwise it won't work */ - if(cd_transfer_flag) - { - int i; - if(WORK_RAM_H(m_scu.dst[dma_ch])) - m_scu.dst_add[dma_ch] = 4; - else - m_scu.dst_add[dma_ch] <<= 1; - - for (i = 0; i < m_scu.size[dma_ch];i+=m_scu.dst_add[dma_ch]) - { - space.write_dword(m_scu.dst[dma_ch],space.read_dword(m_scu.src[dma_ch])); - if(m_scu.dst_add[dma_ch] == 8) - space.write_dword(m_scu.dst[dma_ch]+4,space.read_dword(m_scu.src[dma_ch])); - - m_scu.src[dma_ch]+=m_scu.src_add[dma_ch]; - m_scu.dst[dma_ch]+=m_scu.dst_add[dma_ch]; - } - } - else - { - int i; - uint8_t src_shift; - - src_shift = ((m_scu.src[dma_ch] & 2) >> 1) ^ 1; - - for (i = 0; i < m_scu.size[dma_ch];i+=2) - { - scu_single_transfer(space,m_scu.src[dma_ch],m_scu.dst[dma_ch],&src_shift); - - if(src_shift) - m_scu.src[dma_ch]+=m_scu.src_add[dma_ch]; - - /* if target is Work RAM H, the add value is fixed, behaviour confirmed by Final Romance 2, Virtual Mahjong and Burning Rangers */ - m_scu.dst[dma_ch]+=(WORK_RAM_H(m_scu.dst[dma_ch])) ? 2 : m_scu.dst_add[dma_ch]; - } - } - - /* Burning Rangers doesn't agree with this. */ -// m_scu.size[dma_ch] = 0; - if(!(DRUP(dma_ch))) m_scu.src[dma_ch] = tmp_src; - if(!(DWUP(dma_ch))) m_scu.dst[dma_ch] = tmp_dst; - - { - /*TODO: Timing is a guess. */ - switch(dma_ch) - { - case 0: machine().scheduler().timer_set(m_maincpu->cycles_to_attotime(total_size/4), timer_expired_delegate(FUNC(saturn_state::dma_lv0_ended),this)); break; - case 1: machine().scheduler().timer_set(m_maincpu->cycles_to_attotime(total_size/4), timer_expired_delegate(FUNC(saturn_state::dma_lv1_ended),this)); break; - case 2: machine().scheduler().timer_set(m_maincpu->cycles_to_attotime(total_size/4), timer_expired_delegate(FUNC(saturn_state::dma_lv2_ended),this)); break; - } - } -} - -void saturn_state::scu_dma_indirect(address_space &space,uint8_t dma_ch) -{ - /*Helper to get out of the cycle*/ - uint8_t job_done = 0; - /*temporary storage for the transfer data*/ - uint32_t tmp_src; - uint32_t indirect_src,indirect_dst; - int32_t indirect_size; - uint32_t total_size = 0; - - DnMV_1(dma_ch); - - m_scu.index[dma_ch] = m_scu.dst[dma_ch]; - - do{ - tmp_src = m_scu.index[dma_ch]; - - indirect_size = space.read_dword(m_scu.index[dma_ch]); - indirect_src = space.read_dword(m_scu.index[dma_ch]+8); - indirect_dst = space.read_dword(m_scu.index[dma_ch]+4); - - /*Indirect Mode end factor*/ - if(indirect_src & 0x80000000) - job_done = 1; - - if(m_scu.src_add[dma_ch] == 0 || (m_scu.dst_add[dma_ch] != 2)) - { - if(LOG_SCU) printf("DMA lv %d indirect mode transfer START\n" - "Index %08x Start %08x End %08x Size %04x\n",dma_ch,tmp_src,indirect_src,indirect_dst,indirect_size); - if(LOG_SCU) printf("Start Add %04x Destination Add %04x\n",m_scu.src_add[dma_ch],m_scu.dst_add[dma_ch]); - } - - indirect_src &=0x07ffffff; - indirect_dst &=0x07ffffff; - indirect_size &= ((dma_ch == 0) ? 0xfffff : 0x3ffff); //TODO: Guardian Heroes sets up a 0x23000 transfer for the FMV? - - if(indirect_size == 0) { indirect_size = (dma_ch == 0) ? 0x00100000 : 0x2000; } - - { - int i; - uint8_t src_shift; - - src_shift = ((indirect_src & 2) >> 1) ^ 1; - - for (i = 0; i < indirect_size;i+=2) - { - scu_single_transfer(space,indirect_src,indirect_dst,&src_shift); - - if(src_shift) - indirect_src+=m_scu.src_add[dma_ch]; - - indirect_dst+= (WORK_RAM_H(indirect_dst)) ? 2 : m_scu.dst_add[dma_ch]; - } - } - - /* Guess: Size + data acquire (1 cycle for src/dst/size) */ - total_size += indirect_size + 3*4; - - //if(DRUP(0)) space.write_dword(tmp_src+8,m_scu.src[0]|job_done ? 0x80000000 : 0); - //if(DWUP(0)) space.write_dword(tmp_src+4,m_scu.dst[0]); - - m_scu.index[dma_ch] = tmp_src+0xc; - - }while(job_done == 0); - - { - /*TODO: change DMA into DRQ model. Timing is a guess. */ - switch(dma_ch) - { - case 0: machine().scheduler().timer_set(m_maincpu->cycles_to_attotime(total_size/4), timer_expired_delegate(FUNC(saturn_state::dma_lv0_ended),this)); break; - case 1: machine().scheduler().timer_set(m_maincpu->cycles_to_attotime(total_size/4), timer_expired_delegate(FUNC(saturn_state::dma_lv1_ended),this)); break; - case 2: machine().scheduler().timer_set(m_maincpu->cycles_to_attotime(total_size/4), timer_expired_delegate(FUNC(saturn_state::dma_lv2_ended),this)); break; - } - } -} /**************************************************************************************/ @@ -649,17 +151,6 @@ WRITE8_MEMBER(saturn_state::saturn_backupram_w) m_backupram[offset >> 1] = data; } -void saturn_state::scu_reset(void) -{ - m_scu.ism = 0xbfff; - m_scu.ist = 0; - m_scu.start_factor[0] = 7; - m_scu.start_factor[1] = 7; - m_scu.start_factor[2] = 7; - m_scu.status = 0; -} - - WRITE_LINE_MEMBER(saturn_state::m68k_reset_callback) { @@ -687,21 +178,6 @@ WRITE8_MEMBER(saturn_state::scsp_irq) } } -WRITE_LINE_MEMBER(saturn_state::scsp_to_main_irq) -{ - if(state) - { - if(!(m_scu.ism & IRQ_SOUND_REQ)) - { - m_maincpu->set_input_line_and_vector(9, HOLD_LINE, 0x46); - scu_do_transfer(5); - } - else - m_scu.ist |= (IRQ_SOUND_REQ); - } -} - - /* (Preliminary) explanation about this: @@ -738,24 +214,11 @@ TIMER_DEVICE_CALLBACK_MEMBER(saturn_state::saturn_scanline) if(scanline == 0*y_step) { - if(!(m_scu.ism & IRQ_VBLANK_OUT)) - { - m_maincpu->set_input_line_and_vector(0xe, HOLD_LINE, 0x41); - scu_do_transfer(1); - } - else - m_scu.ist |= (IRQ_VBLANK_OUT); - + m_scu->vblank_out_w(1); } else if(scanline == vblank_line*y_step) { - if(!(m_scu.ism & IRQ_VBLANK_IN)) - { - m_maincpu->set_input_line_and_vector(0xf, HOLD_LINE ,0x40); - scu_do_transfer(0); - } - else - m_scu.ist |= (IRQ_VBLANK_IN); + m_scu->vblank_in_w(1); // flip odd bit here m_vdp2.odd ^= 1; @@ -764,13 +227,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(saturn_state::saturn_scanline) } else if((scanline % y_step) == 0 && scanline < vblank_line*y_step) { - if(!(m_scu.ism & IRQ_HBLANK_IN)) - { - m_maincpu->set_input_line_and_vector(0xd, HOLD_LINE, 0x42); - scu_do_transfer(2); - } - else - m_scu.ist |= (IRQ_HBLANK_IN); + m_scu->hblank_in_w(1); } if(scanline == (vblank_line+1)*y_step) @@ -784,41 +241,10 @@ TIMER_DEVICE_CALLBACK_MEMBER(saturn_state::saturn_scanline) // VDP1 timing needs some HW work anyway so I'm currently firing VDP1 after 8 scanlines for now, will de-anon the timers in a later stage. if(scanline == (vblank_line+8)*y_step) { - if(!(m_scu.ism & IRQ_VDP1_END)) - { - m_maincpu->set_input_line_and_vector(0x2, HOLD_LINE, 0x4d); - scu_do_transfer(6); - } - else - m_scu.ist |= (IRQ_VDP1_END); + m_scu->vdp1_end_w(1); } - if(scanline == (m_scu_regs[36] & 0x3ff)*y_step) - { - if(!(m_scu.ism & IRQ_TIMER_0)) - { - m_maincpu->set_input_line_and_vector(0xc, HOLD_LINE, 0x43 ); - scu_do_transfer(3); - } - else - m_scu.ist |= (IRQ_TIMER_0); - } - - /* TODO: this isn't completely correct */ - if(m_scu_regs[38] & 0x1) - { - if((!(m_scu_regs[38] & 0x100) && (scanline % y_step) == 0) || - ((m_scu_regs[38] & 0x100) && (scanline == (m_scu_regs[36] & 0x3ff)*y_step))) - { - if(!(m_scu.ism & IRQ_TIMER_1)) - { - m_maincpu->set_input_line_and_vector(0xb, HOLD_LINE, 0x44 ); - scu_do_transfer(4); - } - else - m_scu.ist |= (IRQ_TIMER_1); - } - } + m_scu->check_scanline_timers(scanline, y_step); } TIMER_DEVICE_CALLBACK_MEMBER(saturn_state::saturn_slave_scanline ) @@ -900,37 +326,6 @@ GFXDECODE_START( stv ) GFXDECODE_ENTRY( nullptr, 0, tiles16x16x8_layout, 0x00, (0x08*(2+1)) ) GFXDECODE_END -WRITE_LINE_MEMBER(saturn_state::scudsp_end_w) -{ - if(state) - { - if(!(m_scu.ism & IRQ_DSP_END)) - m_maincpu->set_input_line_and_vector(0xa, HOLD_LINE, 0x45); - else - m_scu.ist |= (IRQ_DSP_END); - } -} - -READ16_MEMBER(saturn_state::scudsp_dma_r) -{ - address_space &program = m_maincpu->space(AS_PROGRAM); - offs_t addr = offset; - -// printf("%08x\n",addr); - - return program.read_word(addr,mem_mask); -} - - -WRITE16_MEMBER(saturn_state::scudsp_dma_w) -{ - address_space &program = m_maincpu->space(AS_PROGRAM); - offs_t addr = offset; - -// printf("%08x %02x\n",addr,data); - - program.write_word(addr, data,mem_mask); -} WRITE_LINE_MEMBER( saturn_state::master_sh2_reset_w ) { @@ -962,7 +357,7 @@ WRITE_LINE_MEMBER( saturn_state::system_reset_w ) // TODO: actually send a device reset signal to the connected devices /*Only backup ram and SMPC ram are retained after that this command is issued.*/ - memset(m_scu_regs.get() ,0x00,0x000100); + m_scu->reset(); memset(m_sound_ram,0x00,0x080000); memset(m_workram_h,0x00,0x100000); memset(m_workram_l,0x00,0x100000); @@ -993,15 +388,4 @@ WRITE_LINE_MEMBER(saturn_state::dot_select_w) stv_vdp2_dynamic_res_change(); } -// TODO: to move into SCU device -WRITE_LINE_MEMBER(saturn_state::smpc_irq_w) -{ - if(!state) - return; - - if(!(m_scu.ism & IRQ_SMPC)) - m_maincpu->set_input_line_and_vector(8, HOLD_LINE, 0x47); - else - m_scu.ist |= (IRQ_SMPC); -} |