summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/scudsp/scudsp.c
diff options
context:
space:
mode:
author Angelo Salese <angelosa@users.noreply.github.com>2013-10-10 21:52:51 +0000
committer Angelo Salese <angelosa@users.noreply.github.com>2013-10-10 21:52:51 +0000
commit62854ddd720ec3e565e02bff1e39ae8ad13572c4 (patch)
treeefec39c87fe9eb203cf29413a338cee3344fdab0 /src/emu/cpu/scudsp/scudsp.c
parent8eb5bbee4185e2f917338cd7eac222960add1fcf (diff)
More progresses, Magical Hoppers boots
Diffstat (limited to 'src/emu/cpu/scudsp/scudsp.c')
-rw-r--r--src/emu/cpu/scudsp/scudsp.c127
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;
}