summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/scudsp/scudsp.c
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2015-09-13 08:41:44 +0200
committer Miodrag Milanovic <mmicko@gmail.com>2015-09-13 08:41:44 +0200
commitf88cefad27a1737c76e09d99c9fb43e173506081 (patch)
tree2d8167d03579c46e226471747eb4407bd00ed6fa /src/emu/cpu/scudsp/scudsp.c
parente92ac9e0fa8e99869894bea00589bbb526be30aa (diff)
Move all devices into separate part of src tree (nw)
Diffstat (limited to 'src/emu/cpu/scudsp/scudsp.c')
-rw-r--r--src/emu/cpu/scudsp/scudsp.c1039
1 files changed, 0 insertions, 1039 deletions
diff --git a/src/emu/cpu/scudsp/scudsp.c b/src/emu/cpu/scudsp/scudsp.c
deleted file mode 100644
index 14d1565caa2..00000000000
--- a/src/emu/cpu/scudsp/scudsp.c
+++ /dev/null
@@ -1,1039 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Angelo Salese, Mariusz Wojcieszek
-/*****************************************************************************
- *
- * scudsp.c
- * Sega SCUDSP emulator version 1.00
- *
- * copyright Angelo Salese & Mariusz Wojcieszek, all rights reserved
- *
- * Changelog:
- * 131010: Angelo Salese
- * - Converted to CPU structure
- *
- * 110807: Angelo Salese
- * - Allow the Program Counter to be read-backable from SH-2, needed by Virtua Fighter to not
- * get stuck on "round 1" announcement;
- *
- * 110806: Angelo Salese
- * - Allows reading from non-work ram h areas;
- * - Fixed DMA add values;
- * - Fixed a MVI condition shift flag bug, now Sega Saturn produces sound during splash screen;
- * - Removed left-over IRQ;
- *
- * 110722: Angelo Salese
- * - Added DSP IRQ command, tested with "The King of Boxing"
- *
- * 110527: Angelo Salese
- * - Fixed incorrectly setted execute flag clearance, allows animation of the Sega Saturn
- * splash screen;
- *
- * 051129: Mariusz Wojcieszek
- * - Fixed parallel instructions which increment CT registers to update CT register only
- * once, after dsp operation is finished. This fixes instructions like
- * MOV MC0,X MOV MC0,Y used by vfremix
- * - Changed ALU 32bit instructions to not sign extend their result when loaded to ALU.
- * This matches Sega's dspsim behaviour.
- * - Changed DMA addnumber handling to match Sega's dspsim.
- *
- * 050813: Mariusz Wojcieszek
- * - Fixed add number in DSP DMA
- *
- * 050412: Angelo Salese
- * - Fixed the T0F behaviour in the DMA operation,it was causing an hang in Treasure Hunt
- * due of that.
- * - Removed the dsp.log file creation when you are not using the debug build
- *
- * 041114: Angelo Salese
- * - Finished flags in ALU opcodes
- * - SR opcode: MSB does not change.
- *
- * 040328: Mariusz Wojcieszek
- * - rewritten ALU and MUL operations using signed arithmetics
- * - improved DMA
- * - fixed MOV ALH,x
- *
- * 031211: Mariusz Wojcieszek
- * - result of ALU command is stored into ALU register
- * - X-Bus command: MOV [s],X can be executed in parallel to other X-Bus commands
- * - Y-Bus command: MOV [s],Y can be executed in parallel to other Y-Bus commands
- * - Jump and LPS/BTM support:
- * jump addresses are absolute,
- * prefetched instructions are executed before jump is taken
- * - after each instruction, X and Y is multiplied and contents are loaded into MUL register
- * - fixed RL8
- * - fixed MVI
- * - flags computation in MVI and JMP is partly guessed (because of errors in docs)
- * - added reading DSP mem from SH2 side
- * - overworked disassembler
- *
- * TODO:
- * - Fix INSTA_DMA hack
- * - Fix disassembler
- * - Fix timings (no info available so far)
- * - Add control flags
- * - Croc: has a bug somewhere that never allows it to trip the ENDI opcode.
- * Snippet of interest is:
- * 08 00823500 CLR A MOV M0,PL
- * 09 08040000 OR MOV ALU,A
- * 0A D208000D JMP NZ,$D
- * 0B 00000000 NOP
- * 0C F8000000 ENDI
- *
- * 40 00863502 MOV M0,A MOV M2,PL
- * 41 10003009 ADD MOV ALL,MC0
- * 42 D3400042 JMP T0,$42
- * 43 00000000 NOP
- * 44 D0000007 JMP $7
- *
- *
- *
- *****************************************************************************/
-
-#include "emu.h"
-#include "debugger.h"
-#include "scudsp.h"
-
-
-const device_type SCUDSP = &device_creator<scudsp_cpu_device>;
-
-/* FLAGS */
-#define PRF m_flags & 0x04000000
-#define EPF m_flags & 0x02000000
-#define T0F m_flags & 0x00800000
-#define SF (m_flags & 0x00400000)
-#define ZF (m_flags & 0x00200000)
-#define CF m_flags & 0x00100000
-#define VF m_flags & 0x00080000
-#define EF m_flags & 0x00040000
-#define ESF m_flags & 0x00020000
-#define EXF m_flags & 0x00010000 // execute flag (basically tied to RESET pin)
-#define LEF m_flags & 0x00008000 // change PC value
-#define T0F_1 m_flags|=0x00800000
-#define T0F_0 m_flags&=~0x00800000
-#define EXF_0 m_flags&=~0x00010000
-#define EF_1 m_flags|=0x00040000
-
-#define SET_C(_val) (m_flags = ((m_flags & ~0x00100000) | ((_val) ? 0x00100000 : 0)))
-#define SET_S(_val) (m_flags = ((m_flags & ~0x00400000) | ((_val) ? 0x00400000 : 0)))
-#define SET_Z(_val) (m_flags = ((m_flags & ~0x00200000) | ((_val) ? 0x00200000 : 0)))
-#define SET_V(_val) (m_flags = ((m_flags & ~0x00080000) | ((_val) ? 0x00080000 : 0)))
-
-
-#define FLAGS_MASK 0x06ff8000
-#define INSTA_DMA 1
-
-#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)
-
-UINT32 scudsp_cpu_device::scudsp_get_source_mem_reg_value( UINT32 mode )
-{
- if ( mode < 0x8 )
- {
- return scudsp_get_source_mem_value( mode );
- }
- else
- {
- switch( mode )
- {
- case 0x9:
- return (UINT32)((m_alu & U64(0x00000000ffffffff)) >> 0);
- case 0xA:
- return (UINT32)((m_alu & U64(0x0000ffffffff0000)) >> 16);
- }
- }
- return 0;
-}
-
-UINT32 scudsp_cpu_device::scudsp_get_source_mem_value(UINT8 mode)
-{
- UINT32 value = 0;
-
- switch( mode )
- {
- case 0x0: /* M0 */
- value = scudsp_readmem(m_ct0,0);
- break;
- case 0x1: /* M1 */
- value = scudsp_readmem(m_ct1,1);
- break;
- case 0x2: /* M2 */
- value = scudsp_readmem(m_ct2,2);
- break;
- case 0x3: /* M3 */
- value = scudsp_readmem(m_ct3,3);
- break;
- case 0x4: /* MC0 */
- value = scudsp_readmem(m_ct0++,0);
- m_ct0 &= 0x3f;
- break;
- case 0x5: /* MC1 */
- value = scudsp_readmem(m_ct1++,1);
- m_ct1 &= 0x3f;
- break;
- case 0x6: /* MC2 */
- value = scudsp_readmem(m_ct2++,2);
- m_ct2 &= 0x3f;
- break;
- case 0x7: /* MC3 */
- value = scudsp_readmem(m_ct3++,3);
- m_ct3 &= 0x3f;
- break;
- }
-
- return value;
-}
-
-void scudsp_cpu_device::scudsp_set_dest_mem_reg( UINT32 mode, UINT32 value )
-{
- switch( mode )
- {
- case 0x0: /* MC0 */
- scudsp_writemem(m_ct0++,0,value);
- m_ct0 &= 0x3f;
- break;
- case 0x1: /* MC1 */
- scudsp_writemem(m_ct1++,1,value);
- m_ct1 &= 0x3f;
- break;
- case 0x2: /* MC2 */
- scudsp_writemem(m_ct2++,2,value);
- m_ct2 &= 0x3f;
- break;
- case 0x3: /* MC3 */
- scudsp_writemem(m_ct3++,3,value);
- m_ct3 &= 0x3f;
- break;
- case 0x4: /* RX */
- m_rx.ui = value;
- break;
- case 0x5: /* PL */
- m_pl.ui = value;
- m_ph.si = (m_pl.si < 0) ? -1 : 0;
- break;
- case 0x6: /* RA0 */
- m_ra0 = value;
- break;
- case 0x7: /* WA0 */
- m_wa0 = value;
- break;
- case 0x8:
- case 0x9:
- /* ??? */
- break;
- case 0xa: /* LOP */
- m_lop = value;
- break;
- case 0xb: /* TOP */
- m_top = value;
- break;
- case 0xc: /* CT0 */
- m_ct0 = value & 0x3f;
- break;
- case 0xd: /* CT1 */
- m_ct1 = value & 0x3f;
- break;
- case 0xe: /* CT2 */
- m_ct2 = value & 0x3f;
- break;
- case 0xf: /* CT3 */
- m_ct3 = value & 0x3f;
- break;
- }
-}
-
-void scudsp_cpu_device::scudsp_set_dest_mem_reg_2( UINT32 mode, UINT32 value )
-{
- if ( mode < 0xb )
- {
- scudsp_set_dest_mem_reg( mode, value );
- }
- else
- {
- switch( mode )
- {
- case 0xc: /* PC */
- m_delay = m_pc; /* address next after this command will be executed twice */
- m_top = m_pc;
- m_pc = value;
- break;
- }
- }
-}
-
-UINT32 scudsp_cpu_device::scudsp_compute_condition( UINT32 condition )
-{
- UINT32 result = 0;
-
- switch( condition & 0xf )
- {
- case 0x1: /* Z */
- result = ZF;
- break;
- case 0x2: /* S */
- result = SF;
- break;
- case 0x3: /* ZS */
- result = ZF | SF;
- break;
- case 0x4: /* C */
- result = CF;
- break;
- case 0x8: /* T0 */
- result = T0F;
- break;
- }
- if ( !(condition & 0x20) )
- {
- result = !result;
- }
-
- return result;
-}
-
-void scudsp_cpu_device::scudsp_set_dest_dma_mem( UINT32 memcode, UINT32 value, UINT32 counter )
-{
- if ( memcode < 4 )
- {
- switch(memcode)
- {
- case 0x0: /* MC0 */
- scudsp_writemem(((m_ct0 + counter) & 0x3f),0,value);
- break;
- case 0x1: /* MC1 */
- scudsp_writemem(((m_ct1 + counter) & 0x3f),1,value);
- break;
- case 0x2: /* MC2 */
- scudsp_writemem(((m_ct2 + counter) & 0x3f),2,value);
- break;
- case 0x3: /* MC3 */
- scudsp_writemem(((m_ct3 + counter) & 0x3f),3,value);
- break;
- }
- }
- else if ( memcode == 4 )
- {
- fatalerror("scudsp_set_dest_dma_mem == 4");
- /* caused a stack overflow for sure ... */
- //dsp_reg.internal_prg[ counter & 0x100 ] = value;
- }
-}
-
-UINT32 scudsp_cpu_device::scudsp_get_mem_source_dma( UINT32 memcode, UINT32 counter )
-{
- switch( memcode & 0x3 )
- {
- case 0x0:
- return scudsp_readmem(((m_ct0 + counter) & 0x3f),0);
- case 0x1:
- return scudsp_readmem(((m_ct1 + counter) & 0x3f),1);
- case 0x2:
- return scudsp_readmem(((m_ct2 + counter) & 0x3f),2);
- case 0x3:
- return scudsp_readmem(((m_ct3 + counter) & 0x3f),3);
- }
- return 0;
-}
-
-
-READ32_MEMBER( scudsp_cpu_device::program_control_r )
-{
- return (m_pc & 0xff) | (m_flags & FLAGS_MASK);
-}
-
-WRITE32_MEMBER( scudsp_cpu_device::program_control_w )
-{
- UINT32 oldval, newval;
-
- oldval = (m_flags & 0xffffff00) | (m_pc & 0xff);
- newval = oldval;
- COMBINE_DATA(&newval);
-
- m_flags = newval & FLAGS_MASK;
-
- if(LEF)
- m_pc = newval & 0xff;
-
- //printf("%08x PRG CTRL\n",data);
- set_input_line(INPUT_LINE_RESET, (EXF) ? CLEAR_LINE : ASSERT_LINE);
-}
-
-WRITE32_MEMBER( scudsp_cpu_device::program_w )
-{
- //printf("%02x %08x PRG\n",m_pc,data);
- scudsp_writeop(m_pc++, data);
-}
-
-WRITE32_MEMBER( scudsp_cpu_device::ram_address_control_w )
-{
- //printf("%02x %08x PRG\n",m_pc,data);
- m_ra = data & 0xff;
-
- switch((m_ra & 0xc0) >> 6)
- {
- case 0: m_ct0 = (m_ra & 0x3f); break;
- case 1: m_ct1 = (m_ra & 0x3f); break;
- case 2: m_ct2 = (m_ra & 0x3f); break;
- case 3: m_ct3 = (m_ra & 0x3f); break;
- }
-}
-
-READ32_MEMBER( scudsp_cpu_device::ram_address_r )
-{
- UINT32 data;
-
- data = scudsp_get_source_mem_value( ((m_ra & 0xc0) >> 6) + 4 );
-
- return data;
-}
-
-WRITE32_MEMBER( scudsp_cpu_device::ram_address_w )
-{
- scudsp_set_dest_mem_reg( (m_ra & 0xc0) >> 6, data );
-}
-
-void scudsp_cpu_device::scudsp_operation(UINT32 opcode)
-{
- INT64 i1,i2;
- INT32 i3;
- int update_ct[4] = {0,0,0,0};
- int dsp_mem;
-
-
- /* ALU */
- switch( (opcode & 0x3c000000) >> 26 )
- {
- case 0x0: /* NOP */
- break;
- case 0x1: /* AND */
- i3 = m_acl.si & m_pl.si;
- m_alu = (UINT64)(UINT32)i3;
- SET_Z(i3 == 0);
- SET_C(0);
- SET_S(i3 < 0);
- break;
- case 0x2: /* OR */
- i3 = m_acl.si | m_pl.si;
- m_alu = (UINT64)(UINT32)i3;
- SET_C(0);
- SET_S(i3 < 0);
- /* TODO: Croc and some early Psygnosis games wants Z to be 1 when the result of this one is negative.
- Needs HW tests ... */
- if(i3 < 0)
- i3 = 0;
- SET_Z(i3 == 0);
- break;
- case 0x3: /* XOR */
- i3 = m_acl.si ^ m_pl.si;
- m_alu = (UINT64)(UINT32)i3;
- SET_Z(i3 == 0);
- SET_C(0);
- SET_S(i3 < 0);
- break;
- case 0x4: /* ADD */
- i3 = m_acl.si + m_pl.si;
- m_alu = (UINT64)(UINT32)i3;
- //SET_Z(i3 == 0);
- SET_Z( (i3 & S64(0xffffffffffff)) == 0 );
- //SET_S(i3 < 0);
- SET_S( i3 & S64(0x1000000000000));
- SET_C(i3 & S64(0x100000000));
- SET_V(((i3) ^ (m_acl.si)) & ((i3) ^ (m_pl.si)) & 0x80000000);
- break;
- case 0x5: /* SUB */
- i3 = m_acl.si - m_pl.si;
- m_alu = (UINT64)(UINT32)i3;
- SET_Z(i3 == 0);
- SET_C(i3 & S64(0x100000000));
- SET_S(i3 < 0);
- SET_V(((m_pl.si) ^ (m_acl.si)) & ((m_pl.si) ^ (i3)) & 0x80000000);
- break;
- case 0x6: /* AD2 */
- i1 = CONCAT_64((INT32)m_ph.si,m_pl.si);
- i2 = CONCAT_64((INT32)m_ach.si,m_acl.si);
- m_alu = i1 + i2;
- SET_Z((m_alu & S64(0xffffffffffff)) == 0);
- SET_S((m_alu & S64(0x800000000000)) > 0);
- SET_C((m_alu) & S64(0x1000000000000));
- SET_V(((m_alu) ^ (i1)) & ((m_alu) ^ (i2)) & S64(0x800000000000));
- break;
- case 0x7: /* ??? */
- /* Unrecognized opcode */
- break;
- case 0x8: /* SR */
- i3 = (m_acl.si >> 1) | (m_acl.si & 0x80000000);/*MSB does not change*/
- m_alu = (UINT64)(UINT32)i3;
- SET_Z(i3 == 0);
- SET_S(i3 < 0);
- SET_C(m_acl.ui & 0x80000000);
- break;
- case 0x9: /* RR */
- i3 = ((m_acl.ui >> 1) & 0x7fffffff) | ((m_acl.ui << 31) & 0x80000000);
- m_alu = (UINT64)(UINT32)i3;
- SET_Z( i3 == 0 );
- SET_S( i3 < 0 );
- SET_C( m_acl.ui & 0x1 );
- break;
- case 0xa: /* SL */
- i3 = m_acl.si << 1;
- m_alu = (UINT64)(UINT32)i3;
- SET_Z( i3 == 0 );
- SET_S( i3 < 0 );
- SET_C( m_acl.ui & 0x80000000 );
- break;
- case 0xB: /* RL */
- i3 = ((m_acl.si << 1) & 0xfffffffe) | ((m_acl.si >> 31) & 0x1);
- m_alu = (UINT64)(UINT32)i3;
- SET_Z( i3 == 0 );
- SET_S( i3 < 0 );
- SET_C( m_acl.ui & 0x80000000 );
- break;
- case 0xc:
- case 0xd:
- case 0xe:
- /* Unrecognized opcode */
- break;
- case 0xF: /* RL8 */
- i3 = ((m_acl.si << 8) & 0xffffff00) | ((m_acl.si >> 24) & 0xff);
- m_alu = i3;
- SET_Z( i3 == 0 );
- SET_S( i3 < 0 );
- SET_C( m_acl.si & 0x01000000 );
- break;
- }
-
- /* X-Bus */
- if ( opcode & 0x2000000 )
- {
- /* MOV [s],X */
- dsp_mem = (opcode & 0x700000) >> 20;
- if ( dsp_mem & 4 )
- {
- dsp_mem &= 3;
- update_ct[dsp_mem] = 1;
- }
- m_rx.ui = scudsp_get_source_mem_value( dsp_mem );
- m_update_mul = 1;
- }
- switch( (opcode & 0x1800000) >> 23 )
- {
- case 0x0: /* NOP */
- case 0x1: /* NOP ? */
- break;
- case 0x2: /* MOV MUL,P */
- m_ph.ui = (UINT16)((m_mul & U64(0x0000ffff00000000)) >> 32);
- m_pl.ui = (UINT32)((m_mul & U64(0x00000000ffffffff)) >> 0);
- break;
- case 0x3: /* MOV [s],P */
- dsp_mem = (opcode & 0x700000) >> 20;
- if ( dsp_mem & 4 )
- {
- dsp_mem &= 3;
- update_ct[dsp_mem] = 1;
- }
- m_pl.ui = scudsp_get_source_mem_value( dsp_mem );
- m_ph.si = (m_pl.si < 0) ? -1 : 0;
- break;
- }
-
- /* Y-Bus */
- if ( opcode & 0x80000 )
- {
- /* MOV [s],Y */
- dsp_mem = (opcode & 0x1C000 ) >> 14;
- if (dsp_mem & 4)
- {
- dsp_mem &= 3;
- update_ct[dsp_mem] = 1;
- }
- m_ry.ui = scudsp_get_source_mem_value( dsp_mem );
- m_update_mul = 1;
- }
- switch( (opcode & 0x60000) >> 17 )
- {
- case 0x0: /* NOP */
- break;
- case 0x1: /* CLR A */
- m_acl.ui = 0;
- m_ach.ui = 0;
- break;
- case 0x2: /* MOV ALU,A */
- m_ach.ui = (UINT16)((m_alu & U64(0x0000ffff00000000)) >> 32);
- m_acl.ui = (UINT32)((m_alu & U64(0x00000000ffffffff)) >> 0);
- break;
- case 0x3: /* MOV [s], A */
- dsp_mem = (opcode & 0x1C000 ) >> 14;
- if (dsp_mem & 4)
- {
- dsp_mem &= 3;
- update_ct[dsp_mem] = 1;
- }
- m_acl.ui = scudsp_get_source_mem_value( dsp_mem );
- m_ach.si = ((m_acl.si < 0) ? -1 : 0);
- break;
- }
-
- /* update CT registers */
- if ( update_ct[0] ) { m_ct0++; m_ct0 &= 0x3f; };
- if ( update_ct[1] ) { m_ct1++; m_ct1 &= 0x3f; };
- if ( update_ct[2] ) { m_ct2++; m_ct2 &= 0x3f; };
- if ( update_ct[3] ) { m_ct3++; m_ct3 &= 0x3f; };
-
-
- /* D1-Bus */
- switch( (opcode & 0x3000) >> 12 )
- {
- case 0x0: /* NOP */
- break;
- case 0x1: /* MOV SImm,[d] */
- scudsp_set_dest_mem_reg( (opcode & 0xf00) >> 8, (INT32)(INT8)(opcode & 0xff) );
- break;
- case 0x2:
- /* ??? */
- break;
- case 0x3: /* MOV [s],[d] */
- scudsp_set_dest_mem_reg( (opcode & 0xf00) >> 8, scudsp_get_source_mem_reg_value( opcode & 0xf ) );
- break;
- }
-
- m_icount -= 1;
-}
-
-void scudsp_cpu_device::scudsp_move_immediate( UINT32 opcode )
-{
- UINT32 value;
-
- if ( opcode & 0x2000000 )
- {
- if ( scudsp_compute_condition( (opcode & 0x3F80000 ) >> 19 ) )
- {
- value = opcode & 0x7ffff;
- if ( value & 0x40000 ) value |= 0xfff80000;
- scudsp_set_dest_mem_reg_2( (opcode & 0x3C000000) >> 26, value );
- }
- }
- else
- {
- value = opcode & 0x1ffffff;
- if ( value & 0x1000000 ) value |= 0xfe000000;
- scudsp_set_dest_mem_reg_2( (opcode & 0x3C000000) >> 26, value );
- }
- m_icount -= 1;
-}
-
-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;
- /* HACK ALERT: It looks like that scheduling craps out the m_dma parameters, why this happens I don't know ... */
- #if INSTA_DMA
- {
- UINT32 data;
- if ( m_dma.dir == 0 )
- {
- for(m_dma.count = 0;m_dma.count < m_dma.size; m_dma.count++)
- {
- data = (m_in_dma_cb(m_dma.src)<<16) | m_in_dma_cb(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
- {
- for(m_dma.count = 0;m_dma.count < m_dma.size; m_dma.count++)
- {
- data = scudsp_get_mem_source_dma( m_dma.src, m_dma.count );
-
- m_out_dma_cb(m_dma.dst, data >> 16 );
- m_out_dma_cb(m_dma.dst+2, data & 0xffff );
-
- m_dma.dst += m_dma.add;
-
- if ( m_dma.update )
- {
- m_wa0 += ((1 * m_dma.add) >> 2);
- }
- }
- }
-
- //if(m_dma.count >= m_dma.size)
- {
- m_dma.ex = 0;
- T0F_0;
- }
-
- m_icount -= m_dma.size;
- }
- #endif
-
-
- //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;
-}
-
-void scudsp_cpu_device::scudsp_jump( UINT32 opcode )
-{
- if ( opcode & 0x3f80000 )
- {
- if ( scudsp_compute_condition( (opcode & 0x3f80000) >> 19 ) )
- {
- m_delay = m_pc;
- m_pc = opcode & 0xff;
- }
- }
- else
- {
- m_delay = m_pc;
- m_pc = opcode & 0xff;
- }
-
- m_icount -= 1;
-}
-
-void scudsp_cpu_device::scudsp_loop(UINT32 opcode)
-{
- if ( opcode & 0x8000000 )
- {
- /* LPS */
- if ( m_lop != 0 )
- {
- m_lop--;
- m_delay = m_pc;
- m_pc--;
- }
- }
- else
- {
- /* BTM */
- if ( m_lop != 0 )
- {
- m_lop--;
- m_delay = m_pc;
- m_pc = m_top;
- }
- }
- m_icount -= 1;
-}
-
-void scudsp_cpu_device::scudsp_end(UINT32 opcode)
-{
- if(opcode & 0x08000000)
- {
- /*ENDI*/
- EF_1;
- m_out_irq_cb(1);
- }
-
- EXF_0; /* END / ENDI */
- set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
- m_icount -= 1;
-}
-
-void scudsp_cpu_device::scudsp_illegal(UINT32 opcode)
-{
- fatalerror("scudsp illegal opcode at 0x%04x\n", m_pc);
- m_icount -= 1;
-}
-
-void scudsp_cpu_device::scudsp_exec_dma()
-{
- UINT32 data;
- if ( m_dma.dir == 0 )
- {
- data = (m_in_dma_cb(m_dma.src)<<16) | m_in_dma_cb(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_cb(m_dma.dst, data >> 16 );
- m_out_dma_cb(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.count++;
- if(m_dma.count >= m_dma.size)
- {
- m_dma.ex = 0;
- T0F_0;
- }
-
- m_icount -= 1;
-}
-
-/* Execute cycles */
-void scudsp_cpu_device::execute_run()
-{
- UINT32 opcode;
-
- do
- {
- m_update_mul = 0;
-
- debugger_instruction_hook(this, m_pc);
-
- if ( m_delay )
- {
- opcode = scudsp_readop(m_delay);
- m_delay = 0;
- }
- else
- {
- opcode = scudsp_readop(m_pc);
- m_pc++;
- }
-
- switch( (opcode & 0xc0000000) >> 30 )
- {
- case 0x00: /* 00 */
- scudsp_operation(opcode);
- break;
- case 0x01: /* 01 */
- scudsp_illegal(opcode);
- break;
- case 0x02: /* 10 */
- scudsp_move_immediate(opcode);
- break;
- case 0x03: /* 11 */
- switch( (opcode & 0x30000000) >> 28 )
- {
- case 0x00:
- scudsp_dma(opcode);
- break;
- case 0x01:
- scudsp_jump(opcode);
- break;
- case 0x02:
- scudsp_loop(opcode);
- break;
- case 0x03:
- scudsp_end(opcode);
- break;
- }
- break;
- }
-
- if ( m_update_mul == 1 )
- {
- m_mul = (INT64)m_rx.si * (INT64)m_ry.si;
- m_update_mul = 0;
- }
-
- if (m_dma.ex == 1)
- {
- scudsp_exec_dma();
- }
-
- } while( m_icount > 0 );
-}
-
-void scudsp_cpu_device::device_start()
-{
- m_pc = 0;
- m_flags = 0;
- m_delay = 0;
- m_top = 0;
- m_lop = 0;
- memset(&m_rx, 0x00, sizeof(m_rx));
- m_mul = 0;
- memset(&m_ry, 0x00, sizeof(m_ry));
- m_alu = 0;
- memset(&m_ph, 0x00, sizeof(m_ph));
- memset(&m_pl, 0x00, sizeof(m_pl));
- memset(&m_ach, 0x00, sizeof(m_ach));
- memset(&m_acl, 0x00, sizeof(m_acl));
- m_ra0 = 0;
- m_wa0 = 0;
- m_ra = 0;
- m_ct0 = 0;
- m_ct1 = 0;
- m_ct2 = 0;
- m_ct3 = 0;
- memset(&m_dma, 0x00, sizeof(m_dma));
-
- m_program = &space(AS_PROGRAM);
- m_data = &space(AS_DATA);
-
- save_item(NAME(m_pc));
- save_item(NAME(m_ra));
-
- save_item(NAME(m_ct0));
- save_item(NAME(m_ct1));
- save_item(NAME(m_ct2));
- save_item(NAME(m_ct3));
-
- save_item(NAME(m_flags));
- save_item(NAME(m_delay));
-
- save_item(NAME(m_top));
- save_item(NAME(m_lop));
- save_item(NAME(m_rx.ui));
-
- save_item(NAME(m_mul));
-
- save_item(NAME(m_ry.ui));
-
- save_item(NAME(m_alu));
- save_item(NAME(m_ph.ui));
- save_item(NAME(m_pl.ui));
- save_item(NAME(m_ach.ui));
- save_item(NAME(m_acl.ui));
- save_item(NAME(m_ra0));
- save_item(NAME(m_wa0));
-
- save_item(NAME(m_dma.src));
- save_item(NAME(m_dma.dst));
- save_item(NAME(m_dma.size));
-
- // Register state for debugger
- state_add( SCUDSP_PC, "PC", m_pc ).formatstr("%02X");
- state_add( SCUDSP_FLAGS, "SR", m_flags ).formatstr("%08X");
- state_add( SCUDSP_DELAY, "DELAY", m_delay ).formatstr("%02X").noshow();
- state_add( SCUDSP_TOP, "TOP", m_top).formatstr("%02X");
- state_add( SCUDSP_LOP, "LOP", m_lop).formatstr("%03X");
- state_add( SCUDSP_RX, "RX", m_rx).formatstr("%08X");
- state_add( SCUDSP_MUL, "MUL", m_mul).formatstr("%012X");
- state_add( SCUDSP_RY, "RY", m_ry).formatstr("%08X");
- state_add( SCUDSP_ALU, "ALU", m_alu).formatstr("%012X");
- state_add( SCUDSP_PH, "PH", m_ph).formatstr("%04X");
- state_add( SCUDSP_PL, "PL", m_pl).formatstr("%08X");
- state_add( SCUDSP_ACH, "ACH", m_ach).formatstr("%04X");
- state_add( SCUDSP_ACL, "ACL", m_acl).formatstr("%08X");
- state_add( SCUDSP_RA0, "RA0", m_ra0).formatstr("%08X");
- state_add( SCUDSP_WA0, "WA0", m_wa0).formatstr("%08X");
- state_add( SCUDSP_RA, "RA", m_ra ).formatstr("%02X");
- state_add( SCUDSP_CT0, "CT0", m_ct0 ).formatstr("%02X");
- state_add( SCUDSP_CT1, "CT1", m_ct1 ).formatstr("%02X");
- state_add( SCUDSP_CT2, "CT2", m_ct2 ).formatstr("%02X");
- state_add( SCUDSP_CT3, "CT3", m_ct3 ).formatstr("%02X");
- state_add( STATE_GENPC, "curpc", m_pc ).noshow();
- state_add( STATE_GENFLAGS, "GENFLAGS", m_flags ).formatstr("%17s").noshow();
-
- m_out_irq_cb.resolve_safe();
- m_in_dma_cb.resolve_safe(0);
- m_out_dma_cb.resolve_safe();
-
- m_icountptr = &m_icount;
-}
-
-void scudsp_cpu_device::device_reset()
-{
-}
-
-void scudsp_cpu_device::execute_set_input(int irqline, int state)
-{
- switch(irqline)
- {
- case SCUDSP_RESET:
- //m_reset_state = state;
- break;
- }
-}
-
-scudsp_cpu_device::scudsp_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : cpu_device(mconfig, SCUDSP, "SCUDSP", tag, owner, clock, "scudsp", __FILE__)
- , m_out_irq_cb(*this)
- , m_in_dma_cb(*this)
- , m_out_dma_cb(*this)
- , m_program_config("program", ENDIANNESS_BIG, 32, 8, -2)
- , m_data_config("data", ENDIANNESS_BIG, 32, 8, -2)
-{
-}
-
-
-void scudsp_cpu_device::state_string_export(const device_state_entry &entry, std::string &str)
-{
- switch (entry.index())
- {
- case STATE_GENFLAGS:
- strprintf(str, "%s%s%s%c%c%c%c%c%s%s%s",
- m_flags & 0x4000000 ? "PR":"..",
- m_flags & 0x2000000 ? "EP":"..",
- m_flags & 0x800000 ? "T0":"..",
- m_flags & 0x400000 ? 'S':'.',
- m_flags & 0x200000 ? 'Z':'.',
- m_flags & 0x100000 ? 'C':'.',
- m_flags & 0x80000 ? 'V':'.',
- m_flags & 0x40000 ? 'E':'.',
- m_flags & 0x20000 ? "ES":"..",
- m_flags & 0x10000 ? "EX":"..",
- m_flags & 0x8000 ? "LE":"..");
- break;
- }
-}
-
-
-offs_t scudsp_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
-{
- extern CPU_DISASSEMBLE( scudsp );
- return CPU_DISASSEMBLE_NAME(scudsp)(this, buffer, pc, oprom, opram, options);
-}