summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/machine/saturn.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/machine/saturn.cpp')
-rw-r--r--src/mame/machine/saturn.cpp628
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);
-}