diff options
| author | 2011-01-25 16:14:13 +0000 | |
|---|---|---|
| committer | 2011-01-25 16:14:13 +0000 | |
| commit | 512d2af3b4b97533db18e3fab897d4f634e20fac (patch) | |
| tree | cce77e0a282697a00334d7c7d91be697e796a2a4 /src | |
| parent | 9cb3b37875fe9ffd5557f944cf83b3f10e8a8296 (diff) | |
A new WE DSP16A cpu disassembler. [Andrew Gardner]
Notes out of whatsnew.txt
* This uses modern devices, but has not been tested in a driver yet, so I may
have done something wrong. I will fix it when the time comes.
* 60% of the disassembler is complete. I will finish it over the next few days.
* There are many similarities in execution to the dsp32, and the existing 32 code
will come in handy when it's time to write the execution engine.
* This thing is a pleasure compared to the dsp56k.
Diffstat (limited to 'src')
| -rw-r--r-- | src/emu/cpu/cpu.mak | 14 | ||||
| -rw-r--r-- | src/emu/cpu/dsp16/dsp16.c | 249 | ||||
| -rw-r--r-- | src/emu/cpu/dsp16/dsp16.h | 134 | ||||
| -rw-r--r-- | src/emu/cpu/dsp16/dsp16dis.c | 475 | ||||
| -rw-r--r-- | src/mame/mame.mak | 1 | ||||
| -rw-r--r-- | src/tools/unidasm.c | 2 |
6 files changed, 875 insertions, 0 deletions
diff --git a/src/emu/cpu/cpu.mak b/src/emu/cpu/cpu.mak index ac2ab0ef3b9..dfa18923bc3 100644 --- a/src/emu/cpu/cpu.mak +++ b/src/emu/cpu/cpu.mak @@ -176,6 +176,20 @@ $(CPUOBJ)/apexc/apexc.o: $(CPUSRC)/apexc/apexc.c \ #------------------------------------------------- +# AT&T DSP16A +#------------------------------------------------- + +ifneq ($(filter DSP16A,$(CPUS)),) +OBJDIRS += $(CPUOBJ)/dsp16 +CPUOBJS += $(CPUOBJ)/dsp16/dsp16.o +DASMOBJS += $(CPUOBJ)/dsp16/dsp16dis.o +endif + +$(CPUOBJ)/dsp16/dsp16.o: $(CPUSRC)/dsp16/dsp16.c \ + $(CPUSRC)/dsp16/dsp16.h + + +#------------------------------------------------- # AT&T DSP32C #------------------------------------------------- diff --git a/src/emu/cpu/dsp16/dsp16.c b/src/emu/cpu/dsp16/dsp16.c new file mode 100644 index 00000000000..3d48a6d855a --- /dev/null +++ b/src/emu/cpu/dsp16/dsp16.c @@ -0,0 +1,249 @@ +/*************************************************************************** + + dsp16.h + + WE|AT&T DSP16 series emulator. + +***************************************************************************/ + +#include "emu.h" +#include "debugger.h" +#include "dsp16.h" + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type DSP16 = dsp16_device_config::static_alloc_device_config; + + + +//************************************************************************** +// DSP16 DEVICE CONFIG +//************************************************************************** + +dsp16_device_config::dsp16_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock) + : cpu_device_config(mconfig, static_alloc_device_config, "DSP16", tag, owner, clock), + m_program_config("program", ENDIANNESS_LITTLE, 16, 16, -1) +{ } + + +//------------------------------------------------- +// static_alloc_device_config - allocate a new +// configuration object +//------------------------------------------------- + +device_config *dsp16_device_config::static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock) +{ + return global_alloc(dsp16_device_config(mconfig, tag, owner, clock)); +} + + +//------------------------------------------------- +// alloc_device - allocate a new device object +//------------------------------------------------- + +device_t *dsp16_device_config::alloc_device(running_machine &machine) const +{ + return auto_alloc(&machine, dsp16_device(machine, *this)); +} + + +//------------------------------------------------- +// execute_min_cycles - return minimum number of +// cycles it takes for one instruction to execute +//------------------------------------------------- + +UINT32 dsp16_device_config::execute_min_cycles() const +{ + return 1; +} + + +//------------------------------------------------- +// execute_max_cycles - return maximum number of +// cycles it takes for one instruction to execute +//------------------------------------------------- + +UINT32 dsp16_device_config::execute_max_cycles() const +{ + return 1; +} + + +//------------------------------------------------- +// execute_input_lines - return the number of +// input/interrupt lines +//------------------------------------------------- + +UINT32 dsp16_device_config::execute_input_lines() const +{ + return 1; // TODO +} + + +//------------------------------------------------- +// memory_space_config - return the configuration +// of the specified address space, or NULL if +// the space doesn't exist +//------------------------------------------------- + +const address_space_config *dsp16_device_config::memory_space_config(int spacenum) const +{ + return (spacenum == AS_PROGRAM) ? &m_program_config : NULL; +} + + +//------------------------------------------------- +// disasm_min_opcode_bytes - return the length +// of the shortest instruction, in bytes +//------------------------------------------------- + +UINT32 dsp16_device_config::disasm_min_opcode_bytes() const +{ + return 2; +} + + +//------------------------------------------------- +// disasm_max_opcode_bytes - return the length +// of the longest instruction, in bytes +//------------------------------------------------- + +UINT32 dsp16_device_config::disasm_max_opcode_bytes() const +{ + return 4; +} + + + +//************************************************************************** +// DEVICE INTERFACE +//************************************************************************** + +//------------------------------------------------- +// dsp16_device - constructor +//------------------------------------------------- + +dsp16_device::dsp16_device(running_machine &_machine, const dsp16_device_config &config) + : cpu_device(_machine, config), + m_pc(0), + m_ppc(0), + m_icount(0) +{ + // Allocate & setup +} + + + +//------------------------------------------------- +// device_start - start up the device +//------------------------------------------------- + +void dsp16_device::device_start() +{ + // get our address spaces + m_program = space(AS_PROGRAM); + m_direct = &m_program->direct(); + + state_save_register_device_item(this, 0, m_pc); + + // register state with the debugger + state_add(DSP16_PC, "PC", m_pc); + + // set our instruction counter + m_icountptr = &m_icount; +} + + +//------------------------------------------------- +// device_reset - reset the device +//------------------------------------------------- + +void dsp16_device::device_reset() +{ + m_pc = m_ppc = 0x0000; +} + + +//------------------------------------------------- +// state_import - import state into the device, +// after it has been set +//------------------------------------------------- + +void dsp16_device::state_import(const device_state_entry &entry) +{ + +} + + +//------------------------------------------------- +// state_string_export - export state as a string +// for the debugger +//------------------------------------------------- + +void dsp16_device::state_string_export(const device_state_entry &entry, astring &string) +{ + string.printf(""); +} + + +//------------------------------------------------- +// disasm_disassemble - call the disassembly +// helper function +//------------------------------------------------- + +offs_t dsp16_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) +{ + extern CPU_DISASSEMBLE( dsp16 ); + return CPU_DISASSEMBLE_NAME(dsp16)(NULL, buffer, pc, oprom, opram, 0); +} + + + +/*************************************************************************** + MEMORY ACCESSORS +***************************************************************************/ + +inline UINT32 dsp16_device::program_read(UINT32 addr) +{ + return m_program->read_dword(addr << 1); +} + +inline void dsp16_device::program_write(UINT32 addr, UINT32 data) +{ + m_program->write_dword(addr << 1, data & 0xffff); +} + +inline UINT32 dsp16_device::opcode_read() +{ + return m_direct->read_decrypted_dword(m_pc << 1); +} + + +/*************************************************************************** + CORE EXECUTION LOOP +***************************************************************************/ + +void dsp16_device::execute_set_input(int inputnum, int state) +{ +} + + +void dsp16_device::execute_run() +{ + bool check_debugger = ((device_t::m_machine.debug_flags & DEBUG_FLAG_ENABLED) != 0); + + do + { + // debugging + m_ppc = m_pc; // copy PC to previous PC + if (check_debugger) + debugger_instruction_hook(this, m_pc); + + // instruction fetch + //UINT16 op = opcode_read(); + + m_icount--; + } while (m_icount > 0); +} diff --git a/src/emu/cpu/dsp16/dsp16.h b/src/emu/cpu/dsp16/dsp16.h new file mode 100644 index 00000000000..e4292d52a15 --- /dev/null +++ b/src/emu/cpu/dsp16/dsp16.h @@ -0,0 +1,134 @@ +/*************************************************************************** + + dsp16.h + + WE|AT&T DSP16 series emulator. + +***************************************************************************/ + +#pragma once + +#ifndef __DSP16_H__ +#define __DSP16_H__ + + +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +//#define MCFG_DSP16_CONFIG(_config) +// dsp16_device_config::static_set_config(device, _config); + + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +// device type definition +extern const device_type DSP16; + + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class dsp16_device; + + +// ======================> dsp16_device_config + +class dsp16_device_config : public cpu_device_config +{ + friend class dsp16_device; + + // construction/destruction + dsp16_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock); + +public: + // allocators + static device_config *static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock); + virtual device_t *alloc_device(running_machine &machine) const; + +protected: + // device_config_execute_interface overrides + virtual UINT32 execute_min_cycles() const; + virtual UINT32 execute_max_cycles() const; + virtual UINT32 execute_input_lines() const; + + // device_config_memory_interface overrides + virtual const address_space_config *memory_space_config(int spacenum = 0) const; + + // device_config_disasm_interface overrides + virtual UINT32 disasm_min_opcode_bytes() const; + virtual UINT32 disasm_max_opcode_bytes() const; + + // address spaces + const address_space_config m_program_config; +}; + + + +// ======================> dsp16_device + +class dsp16_device : public cpu_device +{ + friend class dsp16_device_config; + + // construction/destruction + dsp16_device(running_machine &_machine, const dsp16_device_config &config); + +public: + // public interfaces + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + // device_execute_interface overrides + virtual void execute_run(); + virtual void execute_set_input(int inputnum, int state); + + // device_state_interface overrides + virtual void state_import(const device_state_entry &entry); + virtual void state_export(const device_state_entry &entry); + virtual void state_string_export(const device_state_entry &entry, astring &string); + + // device_disasm_interface overrides + virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options); + + + + // CPU registers + UINT16 m_pc; + + // internal stuff + UINT16 m_ppc; + + // memory access + inline UINT32 program_read(UINT32 addr); + inline void program_write(UINT32 addr, UINT32 data); + inline UINT32 opcode_read(); + + // address spaces + address_space* m_program; + direct_read_data* m_direct; + + // other internal states + int m_icount; +}; + + +/*************************************************************************** + REGISTER ENUMERATION +***************************************************************************/ + +enum +{ + DSP16_PC +}; + + +#endif /* __DSP16_H__ */ diff --git a/src/emu/cpu/dsp16/dsp16dis.c b/src/emu/cpu/dsp16/dsp16dis.c new file mode 100644 index 00000000000..710c22454a7 --- /dev/null +++ b/src/emu/cpu/dsp16/dsp16dis.c @@ -0,0 +1,475 @@ +#include "emu.h" +#include "dsp16.h" + +astring disasmF1Field(const UINT8& F1, const UINT8& D, const UINT8& S) +{ + astring ret = ""; + switch (F1) + { + case 0x00: ret.printf("a%d = p p = x*y", D); break; + case 0x01: ret.printf("a%d = a%d + p p = x*y", D, S); break; + case 0x02: ret.printf("p = x*y"); break; + case 0x03: ret.printf("a%d = a%d - p p = x*y", D, S); break; + case 0x04: ret.printf("a$d = p", D); break; + case 0x05: ret.printf("a%d = a%d + p", D, S); break; + case 0x06: ret.printf("NOP"); break; + case 0x07: ret.printf("a%d = a%d - p", D, S); break; + case 0x08: ret.printf("a%d = a%d | y", D, S); break; + case 0x09: ret.printf("a%d = a%d ^ y", D, S); break; + case 0x0a: ret.printf("a%d & y", S); break; + case 0x0b: ret.printf("a%d - y", S); break; + case 0x0c: ret.printf("a%d = y", D); break; + case 0x0d: ret.printf("a%d = a%d + y", D, S); break; + case 0x0e: ret.printf("a%d = a%d & y", D, S); break; + case 0x0f: ret.printf("a%d = a%d - y", D, S); break; + + default: return "UNKNOWN"; + } + return ret; +} + +astring disasmXField(const UINT8& X) +{ + // TODO + return ""; +} + +astring disasmYField(const UINT8& Y) +{ + switch (Y) + { + case 0x00: return "*r0"; + case 0x01: return "*r0++"; + case 0x02: return "*r0--"; + case 0x03: return "*r0++j"; + + case 0x04: return "*r1"; + case 0x05: return "*r1++"; + case 0x06: return "*r1--"; + case 0x07: return "*r1++j"; + + case 0x08: return "*r2"; + case 0x09: return "*r2++"; + case 0x0a: return "*r2--"; + case 0x0b: return "*r2++j"; + + case 0x0c: return "*r3"; + case 0x0d: return "*r3++"; + case 0x0e: return "*r3--"; + case 0x0f: return "*r3++j"; + + default: return "UNKNOWN"; + } + return ""; +} + +astring disasmZField(const UINT8& Z) +{ + switch (Z) + { + case 0x00: return "*r0zp"; + case 0x01: return "*r0pz"; + case 0x02: return "*r0m2"; + case 0x03: return "*r0jk"; + + case 0x04: return "*r1zp"; + case 0x05: return "*r1pz"; + case 0x06: return "*r1m2"; + case 0x07: return "*r1jk"; + + case 0x08: return "*r2zp"; + case 0x09: return "*r2pz"; + case 0x0a: return "*r2m2"; + case 0x0b: return "*r2jk"; + + case 0x0c: return "*r3zp"; + case 0x0d: return "*r3pz"; + case 0x0e: return "*r3m2"; + case 0x0f: return "*r3jk"; + + default: return "UNKNOWN"; + } + return ""; +} + +astring disasmF2Field(const UINT8& F2, const UINT8& D, const UINT8& S) +{ + astring ret = ""; + switch (F2) + { + case 0x00: ret.printf("a%d = a%d >> 1", D, S); break; + case 0x01: ret.printf("a%d = a%d << 1", D, S); break; + case 0x02: ret.printf("a%d = a%d >> 4", D, S); break; + case 0x03: ret.printf("a%d = a%d << 4", D, S); break; + case 0x04: ret.printf("a%d = a%d >> 8", D, S); break; + case 0x05: ret.printf("a%d = a%d << 8", D, S); break; + case 0x06: ret.printf("a%d = a%d >> 16", D, S); break; + case 0x07: ret.printf("a%d = a%d << 16", D, S); break; + + case 0x08: ret.printf("a%d = p", D); break; + case 0x09: ret.printf("a%dh = a%dh + 1", D, S); break; + case 0x0a: ret.printf("RESERVED"); break; + case 0x0b: ret.printf("a%d = rnd(a%d)", D, S); break; + case 0x0c: ret.printf("a%d = y", D); break; + case 0x0d: ret.printf("a%d = a%d + 1", D, S); break; + case 0x0e: ret.printf("a%d = a%d", D, S); break; + case 0x0f: ret.printf("a%d = -a%d", D, S); break; + + default: return "UNKNOWN"; + } + return ""; +} + +astring disasmCONField(const UINT8& CON) +{ + switch (CON) + { + case 0x00: return "mi"; + case 0x01: return "pl"; + case 0x02: return "eq"; + case 0x03: return "ne"; + case 0x04: return "lvs"; + case 0x05: return "lvc"; + case 0x06: return "mvs"; + case 0x07: return "mvc"; + case 0x08: return "heads"; + case 0x09: return "tails"; + case 0x0a: return "c0ge"; + case 0x0b: return "c0lt"; + case 0x0c: return "c1ge"; + case 0x0d: return "c1lt"; + case 0x0e: return "true"; + case 0x0f: return "false"; + case 0x10: return "gt"; + case 0x11: return "le"; + + default: return "RESERVED"; + } + return ""; +} + +astring disasmBField(const UINT8& B) +{ + switch (B) + { + case 0x00: return "return"; + case 0x01: return "ireturn"; + case 0x02: return "goto pt"; + case 0x03: return "call pt"; + case 0x04: + case 0x05: + case 0x06: + case 0x07: return "RESERVED"; + + default: return "UNKNOWN"; + } + return ""; +} + +astring disasmRImmediateField(const UINT8& R) +{ + switch (R) + { + case 0x00: return "j"; + case 0x01: return "k"; + case 0x02: return "rb"; + case 0x03: return "re"; + case 0x04: return "r0"; + case 0x05: return "r1"; + case 0x06: return "r2"; + case 0x07: return "r3"; + + default: return "UNKNOWN"; + } + return ""; +} + +astring disasmRField(const UINT8& R) +{ + switch (R) + { + case 0x00: return "r0"; + case 0x01: return "r1"; + case 0x02: return "r2"; + case 0x03: return "r3"; + case 0x04: return "j"; + case 0x05: return "k"; + case 0x06: return "rb"; + case 0x07: return "re"; + case 0x08: return "pt"; + case 0x09: return "pr"; + case 0x0a: return "pi"; + case 0x0b: return "i"; + + case 0x10: return "x"; + case 0x11: return "y"; + case 0x12: return "yl"; + case 0x13: return "auc"; + case 0x14: return "psw"; + case 0x15: return "c0"; + case 0x16: return "c1"; + case 0x17: return "c2"; + case 0x18: return "soic"; + case 0x19: return "srta"; + case 0x1a: return "sdx"; + case 0x1b: return "tdms"; + case 0x1c: return "pioc"; + case 0x1d: return "pdx0"; + case 0x1e: return "pdx1"; + + default: return "RESERVED"; + } + return ""; +} + +astring disasmIField(const UINT8& I) +{ + switch (I) + { + case 0x00: return "r0/j"; + case 0x01: return "r1/k"; + case 0x02: return "r2/rb"; + case 0x03: return "r3/re"; + + default: return "UNKNOWN"; + } + return ""; +} + +bool disasmSIField(const UINT8& SI) +{ + switch (SI) + { + case 0x00: return 0; // Not a software interrupt + case 0x01: return 1; // Software Interrupt + } + return false; +} + + +/* execute instructions on this CPU until icount expires */ +CPU_DISASSEMBLE( dsp16a ) +{ + UINT8 opSize = 1; + UINT32 dasmflags = 0; + UINT16 op = oprom[0] | (oprom[1] << 8); + UINT16 op2 = oprom[2] | (oprom[3] << 8); + + // TODO: Test for previous "if CON" instruction and tab the next instruction in? + + const UINT8 opcode = (op >> 11) & 0x1f; + switch(opcode) + { + // Format 1: Multiply/ALU Read/Write Group + case 0x06: + { + // F1, Y + const UINT8 Y = (op & 0x000f); + const UINT8 S = (op & 0x0200) >> 9; + const UINT8 D = (op & 0x0400) >> 10; + const UINT8 F1 = (op & 0x01e0) >> 5; + astring yString = disasmYField(Y); + astring f1String = disasmF1Field(F1, D, S); + sprintf(buffer, "%s, %s", f1String.cstr(), yString.cstr()); + opSize = 1; + break; + } + case 0x04: case 0x1c: + { + // F1 Y=a0[1] | F1 Y=a1[1] + // PAGE 3-40 - WIP + break; + } + + case 0x14: case 0x16: + case 0x17: case 0x19: + case 0x1b: case 0x1f: + { + sprintf(buffer, "format 1"); + break; + } + + // Format 1a: Multiply/ALU Read/Write Group (TODO: Seperate) + case 0x07: + { + sprintf(buffer, "format 1a"); + break; + } + + // Format 2: Multiply/ALU Read/Write Group + case 0x15: case 0x1d: + { + sprintf(buffer, "format 2"); + break; + } + + // Format 2a: Multiply/ALU Read/Write Group + case 0x05: + { + sprintf(buffer, "format 2a"); + break; + } + + // Format 3: Special Functions + case 0x12: + case 0x13: + { + // if|ifc CON F2 + const UINT8 CON = (op & 0x001f); + const UINT8 S = (op & 0x0200) >> 9; + const UINT8 D = (op & 0x0400) >> 10; + const UINT8 F2 = (op & 0x01e0) >> 5; + astring f2String = disasmF2Field(F2, D, S); + astring conString = disasmCONField(CON); + if (op & 0x0800) sprintf(buffer, "if %s : %s", conString.cstr(), f2String.cstr()); + else sprintf(buffer, "ifc %s : %s", conString.cstr(), f2String.cstr()); + break; + } + + // Format 4: Branch Direct Group + case 0x00: case 0x01: + case 0x10: case 0x11: + { + // goto|call JA + const UINT16 JA = (op & 0x0fff) | (pc & 0xf000); + if (op & 0x8000) sprintf(buffer, "call 0x%04x", JA); + else sprintf(buffer, "goto 0x%04x", JA); + opSize = 1; + break; + } + + // Format 5: Branch Indirect Group + case 0x18: + { + // goto B + const UINT8 B = (op & 0x0700) >> 8; + astring bString = disasmBField(B); + sprintf(buffer, "%s", bString.cstr()); + opSize = 1; + break; + } + + // Format 6: Contitional Branch Qualifier/Software Interrupt (icall) + case 0x1a: + { + // if CON [goto/call/return] + const UINT8 CON = (op & 0x001f); + astring conString = disasmCONField(CON); + sprintf(buffer, "if %s:", conString.cstr()); + // TODO: Test for invalid ops + // icall + if (op == 0xd40e) sprintf(buffer, "icall"); + opSize = 1; + break; + } + + // Format 7: Data Move Group + case 0x09: case 0x0b: + { + // R = aS + const UINT8 R = (op & 0x03f0) >> 4; + const UINT8 S = (op & 0x1000) >> 12; + astring rString = disasmRField(R); + sprintf(buffer, "%s = %s", rString.cstr(), (S ? "a1" : "a0")); + opSize = 1; + break; + } + case 0x08: + { + // aT = R + const UINT8 R = (op & 0x03f0) >> 4; + const UINT8 aT = (op & 0x0400) >> 10; + astring rString = disasmRField(R); + sprintf(buffer, "%s = %s", (aT ? "a0" : "a1"), rString.cstr()); + opSize = 1; + break; + } + case 0x0f: + { + // R = Y + const UINT8 Y = (op & 0x000f); + const UINT8 R = (op & 0x03f0) >> 4; + astring yString = disasmYField(Y); + astring rString = disasmRField(R); + sprintf(buffer, "%s = %s", rString.cstr(), yString.cstr()); + // TODO: Special case the R == [y, y1, or x] case + opSize = 1; + break; + } + case 0x0c: + { + // Y = R + const UINT8 Y = (op & 0x000f); + const UINT8 R = (op & 0x03f0) >> 4; + astring yString = disasmYField(Y); + astring rString = disasmRField(R); + sprintf(buffer, "%s = %s", yString.cstr(), rString.cstr()); + opSize = 1; + break; + } + case 0x0d: + { + // Z : R + const UINT8 Z = (op & 0x000f); + const UINT8 R = (op & 0x03f0) >> 4; + astring zString = disasmZField(Z); + astring rString = disasmRField(R); + sprintf(buffer, "%s : %s", zString.cstr(), rString.cstr()); + opSize = 1; + break; + } + + // Format 8: Data Move (immediate operand - 2 words) + case 0x0a: + { + // R = N + const UINT8 R = (op & 0x03f0) >> 4; + astring rString = disasmRField(R); + sprintf(buffer, "%s = 0x%x", rString.cstr(), op2); + opSize = 2; + break; + } + + // Format 9: Short Immediate Group + case 0x02: case 0x03: + { + // R = M + const UINT8 M = (op & 0x00ff); + const UINT8 R = (op & 0x0e00) >> 9; + astring rString = disasmRImmediateField(R); + sprintf(buffer, "%s = 0x%02x", rString.cstr(), M); + opSize = 1; + break; + } + + // Format 10: do - redo + case 0x0e: + { + // do|redo K + const UINT8 K = (op & 0x007f); + const UINT8 NI = (op & 0x0780) >> 7; + sprintf(buffer, "do (next %d inst) %d times", NI, K); + // TODO: Limits on K & NI + if (NI == 0x00) + sprintf(buffer, "redo %d\n", K); + opSize = 1; + break; + } + + // RESERVED + case 0x1e: + { + sprintf(buffer, "RESERVED"); + break; + } + + // UNKNOWN + default: + { + sprintf(buffer, "UNKNOWN"); + break; + } + } + + return opSize | dasmflags | DASMFLAG_SUPPORTED; +} diff --git a/src/mame/mame.mak b/src/mame/mame.mak index 82ed71b57c0..3f00e21dc57 100644 --- a/src/mame/mame.mak +++ b/src/mame/mame.mak @@ -76,6 +76,7 @@ CPUS += ESRIP CPUS += MIPS CPUS += SH2 CPUS += SH4 +CPUS += DSP16A CPUS += DSP32C CPUS += PIC16C5X CPUS += PIC16C62X diff --git a/src/tools/unidasm.c b/src/tools/unidasm.c index 9ca559c2c59..f6114683c3d 100644 --- a/src/tools/unidasm.c +++ b/src/tools/unidasm.c @@ -102,6 +102,7 @@ CPU_DISASSEMBLE( cp1610 ); CPU_DISASSEMBLE( cquestsnd ); CPU_DISASSEMBLE( cquestrot ); CPU_DISASSEMBLE( cquestlin ); +CPU_DISASSEMBLE( dsp16a ); CPU_DISASSEMBLE( dsp32c ); CPU_DISASSEMBLE( dsp56k ); CPU_DISASSEMBLE( hyperstone_generic ); @@ -227,6 +228,7 @@ static const dasm_table_entry dasm_table[] = { "cquestsnd", _64be, -3, CPU_DISASSEMBLE_NAME(cquestsnd) }, { "cquestrot", _64be, -3, CPU_DISASSEMBLE_NAME(cquestrot) }, { "cquestlin", _64be, -3, CPU_DISASSEMBLE_NAME(cquestlin) }, + { "dsp16a", _16le, -1, CPU_DISASSEMBLE_NAME(dsp16a) }, { "dsp32c", _32le, 0, CPU_DISASSEMBLE_NAME(dsp32c) }, { "dsp56k", _16le, -1, CPU_DISASSEMBLE_NAME(dsp56k) }, { "hyperstone", _16be, 0, CPU_DISASSEMBLE_NAME(hyperstone_generic) }, |
