diff options
author | 2013-10-10 21:52:51 +0000 | |
---|---|---|
committer | 2013-10-10 21:52:51 +0000 | |
commit | 62854ddd720ec3e565e02bff1e39ae8ad13572c4 (patch) | |
tree | efec39c87fe9eb203cf29413a338cee3344fdab0 /src/emu/cpu/scudsp/scudsp.c | |
parent | 8eb5bbee4185e2f917338cd7eac222960add1fcf (diff) |
More progresses, Magical Hoppers boots
Diffstat (limited to 'src/emu/cpu/scudsp/scudsp.c')
-rw-r--r-- | src/emu/cpu/scudsp/scudsp.c | 127 |
1 files changed, 124 insertions, 3 deletions
diff --git a/src/emu/cpu/scudsp/scudsp.c b/src/emu/cpu/scudsp/scudsp.c index 1f4cc455ccb..526162cd429 100644 --- a/src/emu/cpu/scudsp/scudsp.c +++ b/src/emu/cpu/scudsp/scudsp.c @@ -130,8 +130,8 @@ const device_type SCUDSP = &device_creator<scudsp_cpu_device>; #define scudsp_readop(A) m_program->read_dword(A << 2) #define scudsp_writeop(A, B) m_program->write_dword(A << 2, B) -#define scudsp_readmem(A,MD) m_data->read_dword(((A | MD) << 6) << 2) -#define scudsp_writemem(A,MD,B) m_data->write_dword(((A | MD) << 6) << 2, B) +#define scudsp_readmem(A,MD) m_data->read_dword((A | (MD << 6)) << 2) +#define scudsp_writemem(A,MD,B) m_data->write_dword((A | (MD << 6)) << 2, B) UINT32 scudsp_cpu_device::scudsp_get_source_mem_reg_value( UINT32 mode ) { @@ -616,6 +616,57 @@ void scudsp_cpu_device::scudsp_move_immediate( UINT32 opcode ) void scudsp_cpu_device::scudsp_dma( UINT32 opcode ) { + UINT8 hold = (opcode & 0x4000) >> 14; + UINT32 add = (opcode & 0x38000) >> 15; + UINT32 dir_from_D0 = (opcode & 0x1000 ) >> 12; + UINT32 dsp_mem = (opcode & 0x300) >> 8; + + T0F_1; + + if ( opcode & 0x2000 ) + { + m_dma.size = scudsp_get_source_mem_value( opcode & 0xf ); + switch ( add & 0x7 ) + { + case 0: m_dma.add = 0; break; + case 1: m_dma.add = 4; break; + default: m_dma.add = 4; break; + } + } + else + { + m_dma.size = opcode & 0xff; + switch( add ) + { + case 0: m_dma.add = 0; break; /* 0 */ + case 1: m_dma.add = 4; break; /* 1 */ + case 2: m_dma.add = 4; break; /* 2 */ + case 3: m_dma.add = 16; break; /* 4 */ + case 4: m_dma.add = 16; break; /* 8 */ + case 5: m_dma.add = 64; break; /* 16 */ + case 6: m_dma.add = 128; break; /* 32 */ + case 7: m_dma.add = 256; break; /* 64 */ + } + } + + m_dma.dir = dir_from_D0; + if ( m_dma.dir == 0 ) + { + m_dma.src = (m_ra0 << 2) & 0x07ffffff; + m_dma.dst = dsp_mem; + } + else + { + m_dma.src = dsp_mem; + m_dma.dst = (m_wa0 << 2) & 0x07ffffff; + } + + m_dma.update = ( hold == 0 ); + m_dma.ex = 1; + m_dma.count = 0; + + //printf("SRC %08x DST %08x SIZE %08x UPDATE %08x DIR %08x ADD %08x\n",m_dma.src,m_dma.dst,m_dma.size,m_dma.update,m_dma.dir,m_dma.add); + m_icount -= 1; } @@ -668,9 +719,10 @@ void scudsp_cpu_device::scudsp_end(UINT32 opcode) if(opcode & 0x08000000) { /*ENDI*/ - //TODO: irq signal + m_out_irq_func(1); } + EF_1; // ok? EXF_0; /* END / ENDI */ set_input_line(INPUT_LINE_RESET, ASSERT_LINE); m_icount -= 1; @@ -682,6 +734,47 @@ void scudsp_cpu_device::scudsp_illegal(UINT32 opcode) m_icount -= 1; } +void scudsp_cpu_device::scudsp_exec_dma() +{ + UINT32 data; + if ( m_dma.dir == 0 ) + { + data = (m_in_dma_func(m_dma.src)<<16) | m_in_dma_func(m_dma.src+2); + scudsp_set_dest_dma_mem( m_dma.dst, data, m_dma.count++ ); + + m_dma.src += m_dma.add; + + if ( m_dma.update ) + { + m_ra0 += ((1 * m_dma.add) >> 2); + } + } + else + { + data = scudsp_get_mem_source_dma( m_dma.src, m_dma.count++ ); + + m_out_dma_func(m_dma.dst, data >> 16 ); + m_out_dma_func(m_dma.dst+2, data & 0xffff ); + + m_dma.dst += m_dma.add; + + if ( m_dma.update ) + { + m_wa0 += ((1 * m_dma.add) >> 2); + } + } + + m_dma.size--; + + if(m_dma.size == 0) + { + m_dma.ex = 0; + T0F_0; + } + + m_icount -= 1; +} + /* Execute cycles */ void scudsp_cpu_device::execute_run() { @@ -740,10 +833,34 @@ void scudsp_cpu_device::execute_run() m_update_mul = 0; } + if (m_dma.ex == 1) + { + scudsp_exec_dma(); + } } while( m_icount > 0 ); } +//------------------------------------------------- +// device_config_complete - perform any +// operations now that the configuration is +// complete +//------------------------------------------------- + +void scudsp_cpu_device::device_config_complete() +{ + // inherit a copy of the static data + const scudsp_interface *intf = reinterpret_cast<const scudsp_interface *>(static_config()); + if (intf != NULL) + *static_cast<scudsp_interface *>(this) = *intf; + + // or error out if none provided + else + { + fatalerror("SCUDSP_INTERFACE for cpu '%s' not defined!\n", tag()); + } +} + void scudsp_cpu_device::device_start() { @@ -801,6 +918,10 @@ void scudsp_cpu_device::device_start() state_add( STATE_GENPC, "curpc", m_pc ).noshow(); state_add( STATE_GENFLAGS, "GENFLAGS", m_flags ).formatstr("%17s").noshow(); + m_out_irq_func.resolve(m_out_irq_cb, *this); + m_in_dma_func.resolve(m_in_dma_cb, *this); + m_out_dma_func.resolve(m_out_dma_cb, *this); + m_icountptr = &m_icount; } |