diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua index 2a83be1f0ad..08ab14077a2 100644 --- a/scripts/src/cpu.lua +++ b/scripts/src/cpu.lua @@ -3031,3 +3031,20 @@ if (CPUS["PACE"]~=null or _OPTIONS["with-tools"]) then table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/pace/pacedasm.cpp") table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/pace/pacedasm.h") end + +-------------------------------------------------- +-- AT&T WE32000/WE32100/WE32200 +--@src/devices/cpu/we32000/we32100.h,CPUS["WE32000"] = true +-------------------------------------------------- + +if (CPUS["WE32000"]~=null) then + files { + MAME_DIR .. "src/devices/cpu/we32000/we32100.cpp", + MAME_DIR .. "src/devices/cpu/we32000/we32100.h", + } +end + +if (CPUS["WE32000"]~=null or _OPTIONS["with-tools"]) then + table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/we32000/we32100d.cpp") + table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/we32000/we32100d.h") +end diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 127eaa0efa4..44d51e4577d 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -150,6 +150,7 @@ CPUS["FR"] = true CPUS["DSP56000"] = true CPUS["VT50"] = true CPUS["PACE"] = true +CPUS["WE32000"] = true -------------------------------------------------- -- specify available sound cores; some of these are @@ -1752,6 +1753,7 @@ files { createMESSProjects(_target, _subtarget, "att") files { + MAME_DIR .. "src/mame/drivers/att3b2.cpp", MAME_DIR .. "src/mame/drivers/att4425.cpp", MAME_DIR .. "src/mame/drivers/att610.cpp", MAME_DIR .. "src/mame/drivers/att630.cpp", diff --git a/src/devices/cpu/we32000/we32100.cpp b/src/devices/cpu/we32000/we32100.cpp new file mode 100644 index 00000000000..1d4b5fbcd04 --- /dev/null +++ b/src/devices/cpu/we32000/we32100.cpp @@ -0,0 +1,113 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + AT&T WE32100 32-Bit Microprocessor + + Currently this device is just a stub with no actual execution core. + +***************************************************************************/ + +#include "emu.h" +#include "we32100.h" +#include "we32100d.h" + +// device type definitions +DEFINE_DEVICE_TYPE(WE32100, we32100_device, "we32100", "AT&T WE32100") + +we32100_device::we32100_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : cpu_device(mconfig, WE32100, tag, owner, clock) + , m_space_config("program", ENDIANNESS_BIG, 32, 32, 0) + , m_space(nullptr) + , m_cache(nullptr) + , m_r{0} + , m_icount(0) +{ +} + +std::unique_ptr we32100_device::create_disassembler() +{ + return std::make_unique(); +} + +device_memory_interface::space_config_vector we32100_device::memory_space_config() const +{ + return space_config_vector { + std::make_pair(AS_PROGRAM, &m_space_config), + }; +} + +void we32100_device::device_start() +{ + m_space = &space(AS_PROGRAM); + m_cache = m_space->cache<2, 0, ENDIANNESS_BIG>(); + + set_icountptr(m_icount); + + state_add(STATE_GENPC, "GENPC", m_r[15]).noshow(); + state_add(STATE_GENPCBASE, "CURPC", m_r[15]).noshow(); + state_add(STATE_GENFLAGS, "CURFLAGS", m_r[11]).noshow().formatstr("%23s"); + for (int i = 0; i < 9; i++) + state_add(WE_R0 + i, string_format("r%d", i).c_str(), m_r[i]); + for (int i = 9; i < 15; i++) + state_add(WE_R0 + i, string_format("r%d", i).c_str(), m_r[i]).noshow(); + state_add(WE_FP, "FP", m_r[9]); + state_add(WE_AP, "AP", m_r[10]); + state_add(WE_PSW, "PSW", m_r[11]); + state_add(WE_SP, "SP", m_r[12]); + state_add(WE_PCBP, "PCBP", m_r[13]); + state_add(WE_ISP, "ISP", m_r[14]); + state_add(WE_PC, "PC", m_r[15]); + + save_item(NAME(m_r)); +} + +void we32100_device::device_reset() +{ + // TODO +} + +void we32100_device::execute_run() +{ + // On-reset sequence: load PCBP, then load PSW, PC and SP from there + m_r[13] = m_space->read_dword(0x00000080); + m_r[11] = m_space->read_dword(m_r[13]); + m_r[15] = m_space->read_dword(m_r[13] + 4); + m_r[12] = m_space->read_dword(m_r[13] + 8); + + debugger_instruction_hook(m_r[15]); + + m_icount = 0; +} + +void we32100_device::execute_set_input(int inputnum, int state) +{ + // TODO +} + +void we32100_device::state_string_export(const device_state_entry &entry, std::string &str) const +{ + switch (entry.index()) + { + case STATE_GENFLAGS: + str = string_format("%c%c%c%c%c%c%c%c%c<%X>%c(%c)%c%c<%X>%c%c", + BIT(m_r[11], 25) ? 'f' : '.', + BIT(m_r[11], 24) ? 'Q' : '.', + BIT(m_r[11], 23) ? 'c' : '.', + BIT(m_r[11], 22) ? 'O' : '.', + BIT(m_r[11], 21) ? 'N' : '.', + BIT(m_r[11], 20) ? 'Z' : '.', + BIT(m_r[11], 19) ? 'V' : '.', + BIT(m_r[11], 18) ? 'C' : '.', + BIT(m_r[11], 17) ? 'T' : '.', + (m_r[11] & 0x0001e000) >> 13, + "KESU"[(m_r[11] & 0x00001800) >> 11], + "KESU"[(m_r[11] & 0x00000600) >> 9], + BIT(m_r[11], 8) ? 'R' : '.', + BIT(m_r[11], 7) ? 'I' : '.', + (m_r[11] & 0x00000078) >> 3, + BIT(m_r[11], 2) ? 'T' : '.', + "RPSN"[m_r[11] & 0x00000003]); + break; + } +} diff --git a/src/devices/cpu/we32000/we32100.h b/src/devices/cpu/we32000/we32100.h new file mode 100644 index 00000000000..54e1edc4a3e --- /dev/null +++ b/src/devices/cpu/we32000/we32100.h @@ -0,0 +1,59 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + AT&T WE32100 32-Bit Microprocessor + +***************************************************************************/ + +#ifndef MAME_CPU_WE32000_WE32100_H +#define MAME_CPU_WE32000_WE32100_H + +#pragma once + + +class we32100_device : public cpu_device +{ +public: + enum { + WE_R0, WE_R1, WE_R2, WE_R3, WE_R4, WE_R5, WE_R6, WE_R7, WE_R8, + WE_R9, WE_R10, WE_R11, WE_R12, WE_R13, WE_R14, WE_R15, + WE_FP, WE_AP, WE_PSW, WE_SP, WE_PCBP, WE_ISP, WE_PC + }; + + // construction/destruction + we32100_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // device_execute_interface overrides + virtual void execute_run() override; + virtual void execute_set_input(int inputnum, int state) override; + + // device_disasm_interface overrides + virtual std::unique_ptr create_disassembler() override; + + // device_memory_interface overrides + virtual space_config_vector memory_space_config() const override; + + // device_state_interface overrides + void state_string_export(const device_state_entry &entry, std::string &str) const override; + +private: + // address space + address_space_config m_space_config; + address_space *m_space; + memory_access_cache<2, 0, ENDIANNESS_BIG> *m_cache; + + // internal state + u32 m_r[16]; + s32 m_icount; +}; + +// device type declaration +DECLARE_DEVICE_TYPE(WE32100, we32100_device) + +#endif // MAME_CPU_WE32000_WE32100_H diff --git a/src/devices/cpu/we32000/we32100d.cpp b/src/devices/cpu/we32000/we32100d.cpp new file mode 100644 index 00000000000..c33aba03290 --- /dev/null +++ b/src/devices/cpu/we32000/we32100d.cpp @@ -0,0 +1,859 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + Disassembler for AT&T's WE32100 processor. + + Operands are formatted similarly to AT&T's m32dis. Note that operand + encoding is little-endian even though memory accesses are big-endian. + +***************************************************************************/ + +#include "emu.h" +#include "we32100d.h" + + +//************************************************************************** +// WE32100 DISASSEMBLER +//************************************************************************** + +we32100_disassembler::we32100_disassembler() + : util::disasm_interface() +{ +} + +u32 we32100_disassembler::opcode_alignment() const +{ + return 1; +} + +const char *const we32100_disassembler::s_rnames[16] = { + "r0", + "r1", + "r2", + "r3", + "r4", + "r5", + "r6", + "r7", + "r8", + "fp", // Frame Pointer + "ap", // Argument Pointer + "psw", // Processor Status Word (privileged) + "sp", // Stack Pointer + "pcbp", // Process Control Block Pointer (privileged) + "isp", // Interrupt Stack Pointer (privileged) + "pc" // Program Counter +}; + +void we32100_disassembler::format_signed(std::ostream &stream, s32 x) +{ + if (x == 0) + stream << "0"; + else if (x > 0) + util::stream_format(stream, "0x%x", x); + else + util::stream_format(stream, "-0x%x", u32(-x)); +} + +void we32100_disassembler::dasm_am(std::ostream &stream, offs_t &pc, const we32100_disassembler::data_buffer &opcodes, u8 n, bool dst) +{ + switch (n & 0xf0) + { + case 0x00: case 0x10: case 0x20: case 0x30: case 0xf0: + if (dst) + util::stream_format(stream, "invalid(0x%02x)", n); + else + { + stream << "&"; + format_signed(stream, s8(n)); + } + break; + + case 0x40: + if (n != 0x4f) + util::stream_format(stream, "%%%s", s_rnames[n & 0x0f]); + else if (dst) + util::stream_format(stream, "invalid(0x%02x)", n); + else + { + util::stream_format(stream, "&0x%08x", swapendian_int32(opcodes.r32(pc))); + pc += 4; + } + break; + + case 0x50: + if (n != 0x5b && n != 0x5f) + util::stream_format(stream, "(%%%s)", s_rnames[n & 0x0f]); + else if (n == 0x5b || dst) + util::stream_format(stream, "invalid(0x%02x)", n); + else + { + util::stream_format(stream, "&0x%04x", swapendian_int16(opcodes.r16(pc))); + pc += 2; + } + break; + + case 0x60: + if (n != 0x6f) + { + format_signed(stream, n & 0x0f); + stream << "(%fp)"; + } + else if (dst) + util::stream_format(stream, "invalid(0x%02x)", n); + else + util::stream_format(stream, "&0x%02x", opcodes.r8(pc++)); + break; + + case 0x70: + if (n != 0x7f) + { + format_signed(stream, n & 0x0f); + stream << "(%ap)"; + } + else + { + util::stream_format(stream, "$0x%08x", swapendian_int32(opcodes.r32(pc))); + pc += 4; + } + break; + + case 0x80: case 0x90: + if ((n & 0x0f) == 0x0b) + util::stream_format(stream, "invalid(0x%02x)", n); + else + { + if (BIT(n, 4)) + stream << "*"; + format_signed(stream, s32(swapendian_int32(opcodes.r32(pc)))); + pc += 4; + util::stream_format(stream, "(%%%s)", s_rnames[n & 0x0f]); + } + break; + + case 0xa0: case 0xb0: + if ((n & 0x0f) == 0x0b) + util::stream_format(stream, "invalid(0x%02x)", n); + else + { + if (BIT(n, 4)) + stream << "*"; + format_signed(stream, s16(swapendian_int16(opcodes.r16(pc)))); + pc += 2; + util::stream_format(stream, "(%%%s)", s_rnames[n & 0x0f]); + } + break; + + case 0xc0: case 0xd0: + if ((n & 0x0f) == 0x0b) + util::stream_format(stream, "invalid(0x%02x)", n); + else + { + if (BIT(n, 4)) + stream << "*"; + format_signed(stream, s8(opcodes.r8(pc++))); + util::stream_format(stream, "(%%%s)", s_rnames[n & 0x0f]); + } + break; + + case 0xe0: + if (n == 0xef) + { + util::stream_format(stream, "*$0x%08x", swapendian_int32(opcodes.r32(pc))); + pc += 4; + } + else if (BIT(n, 3) || (n & 0x03) == 0x01) + util::stream_format(stream, "reserved(0x%02x)", n); + else + { + if (!BIT(n, 0)) + util::stream_format(stream, "{%cword}", BIT(n, 2) ? 's' : 'u'); + else if (!BIT(n, 1)) + util::stream_format(stream, "{%chalf}", BIT(n, 2) ? 's' : 'u'); + else + util::stream_format(stream, "{%cbyte}", BIT(n, 2) ? 's' : 'u'); + u8 m = opcodes.r8(pc++); + dasm_am(stream, pc, opcodes, m, dst); + } + break; + } +} + +void we32100_disassembler::dasm_src(std::ostream &stream, offs_t &pc, const we32100_disassembler::data_buffer &opcodes) +{ + u8 n = opcodes.r8(pc++); + dasm_am(stream, pc, opcodes, n, false); +} + +void we32100_disassembler::dasm_srcw(std::ostream &stream, offs_t &pc, const we32100_disassembler::data_buffer &opcodes) +{ + u8 n = opcodes.r8(pc++); + if (n < 0xe0 || n >= 0xef) + dasm_am(stream, pc, opcodes, n, false); + else + util::stream_format(stream, "invalid(0x%02x)", n); +} + +void we32100_disassembler::dasm_dst(std::ostream &stream, offs_t &pc, const we32100_disassembler::data_buffer &opcodes) +{ + u8 n = opcodes.r8(pc++); + dasm_am(stream, pc, opcodes, n, true); +} + +void we32100_disassembler::dasm_dstw(std::ostream &stream, offs_t &pc, const we32100_disassembler::data_buffer &opcodes) +{ + u8 n = opcodes.r8(pc++); + if (n < 0xe0 || n == 0xef) + dasm_am(stream, pc, opcodes, n, true); + else + util::stream_format(stream, "invalid(0x%02x)", n); +} + +void we32100_disassembler::dasm_ea(std::ostream &stream, offs_t &pc, const we32100_disassembler::data_buffer &opcodes) +{ + u8 n = opcodes.r8(pc++); + if (n >= 0x50 && (n < 0xe0 || n == 0xef) && n != 0x5f && n != 0x6f) + dasm_am(stream, pc, opcodes, n, false); + else + util::stream_format(stream, "invalid(0x%02x)", n); +} + +void we32100_disassembler::dasm_sr(std::ostream &stream, offs_t &pc, const we32100_disassembler::data_buffer &opcodes) +{ + u8 n = opcodes.r8(pc++); + if (n >= 0x40 && n <= 0x49) + util::stream_format(stream, "%%%s", s_rnames[n & 0x0f]); + else + util::stream_format(stream, "invalid(0x%02x)", n); +} + +void we32100_disassembler::dasm_bdisp(std::ostream &stream, offs_t &pc, const we32100_disassembler::data_buffer &opcodes, bool byte) +{ + u32 ppc = pc - 1; + int disp; + if (byte) + { + disp = s8(opcodes.r8(pc++)); + } + else + { + disp = s16(swapendian_int16(opcodes.r16(pc))); + pc += 2; + } + format_signed(stream, disp); + util::stream_format(stream, " <%x>", u32(ppc + disp)); +} + +offs_t we32100_disassembler::dasm_30xx(std::ostream &stream, offs_t &pc, const we32100_disassembler::data_buffer &opcodes) +{ + u32 flags = SUPPORTED; + u8 op = opcodes.r8(pc++); + + switch (op) + { case 0x09: + stream << "MVERNO"; + break; + + case 0x0d: + stream << "ENBVJMP"; // (privileged) + break; + + case 0x13: + stream << "DISVJMP"; // (privileged) + break; + + case 0x19: + stream << "MOVBLW"; + break; + + case 0x1f: + stream << "STREND"; + break; + + case 0x2f: + stream << "INTACK"; // (privileged) + break; + + case 0x35: + stream << "STRCPY"; + break; + + case 0x45: + stream << "RETG"; + flags |= STEP_OUT; + break; + + case 0x61: + stream << "GATE"; + flags |= STEP_OVER; + break; + + case 0xac: + stream << "CALLPS"; // (privileged) + flags |= STEP_OVER; + break; + + case 0xc8: + stream << "RETPS"; // (privileged) + flags |= STEP_OUT; + break; + + default: + stream << "reserved"; + break; + } + + return flags; +} + +offs_t we32100_disassembler::disassemble(std::ostream &stream, offs_t pc, const we32100_disassembler::data_buffer &opcodes, const we32100_disassembler::data_buffer ¶ms) +{ + offs_t ppc = pc; + u32 flags = SUPPORTED; + u8 op = opcodes.r8(pc++); + + if ((op & 0x03) == 0x01 + || op == 0x00 + || op == 0x26 + || (op & 0xfa) == 0x0a + || (op & 0xfd) == 0x12 + || (op & 0xfe) == 0x1a + || (op & 0xfc) == 0x98 + || (op & 0xde) == 0xc2 + || (op & 0xfe) == 0xd6 + || (op & 0xfe) == 0xda) + { + stream << "reserved"; + } + else switch (op & 0xfc) + { + case 0x00: case 0x04: + if (!BIT(op, 1)) + { + util::stream_format(stream, "%-8s", "MOVAW"); + dasm_ea(stream, pc, opcodes); + stream << ","; + dasm_dst(stream, pc, opcodes); + } + else if (!BIT(op, 0)) + { + util::stream_format(stream, "%-8s0x%08x,", BIT(op, 4) ? "SPOPRT" : "SPOPRD", swapendian_int32(opcodes.r32(pc))); + pc += 4; + dasm_src(stream, pc, opcodes); + } + else + { + util::stream_format(stream, "%-8s0x%08x,", BIT(op, 4) ? "SPOPT2" : "SPOPD2", swapendian_int32(opcodes.r32(pc))); + pc += 4; + dasm_src(stream, pc, opcodes); + stream << ","; + dasm_dst(stream, pc, opcodes); + } + break; + + case 0x08: + stream << "RET"; + flags |= STEP_OUT; + break; + + case 0x0c: + util::stream_format(stream, "%-8s", "MOVTRW"); // (privileged) + dasm_src(stream, pc, opcodes); // or effective address? + stream << ","; + dasm_dst(stream, pc, opcodes); + break; + + case 0x10: + if (!BIT(op, 1)) + { + util::stream_format(stream, "%-8s", "SAVE"); + dasm_sr(stream, pc, opcodes); + } + else + { + util::stream_format(stream, "%-8s0x%08x,", "SPOPWD", swapendian_int32(opcodes.r32(pc))); + pc += 4; + dasm_dst(stream, pc, opcodes); + } + break; + + case 0x14: + if (!BIT(op, 1)) + { + util::stream_format(stream, "%-8s0x%02x", "EXTOP", opcodes.r8(pc++)); + flags |= STEP_OVER; + } + else + { + util::stream_format(stream, "%-8s0x%08x,", "SPOPWT", swapendian_int32(opcodes.r32(pc))); + pc += 4; + dasm_dst(stream, pc, opcodes); + } + break; + + case 0x18: + util::stream_format(stream, "%-8s", "RESTORE"); + dasm_sr(stream, pc, opcodes); + break; + + case 0x1c: + util::stream_format(stream, "%-8s", util::string_format("SWAP%cI", "W?HB"[op & 0x03])); + dasm_ea(stream, pc, opcodes); + break; + + case 0x20: + if (!BIT(op, 1)) + { + util::stream_format(stream, "%-8s", "POPW"); + dasm_dstw(stream, pc, opcodes); + } + else if (!BIT(op, 0)) + { + util::stream_format(stream, "%-8s0x%08x,", "SPOPRS", swapendian_int32(opcodes.r32(pc))); + pc += 4; + dasm_src(stream, pc, opcodes); + } + else + { + util::stream_format(stream, "%-8s0x%08x,", "SPOPS2", swapendian_int32(opcodes.r32(pc))); + pc += 4; + dasm_src(stream, pc, opcodes); + stream << ","; + dasm_dst(stream, pc, opcodes); + } + break; + + case 0x24: + if (!BIT(op, 1)) + { + util::stream_format(stream, "%-8s", "JMP"); + dasm_ea(stream, pc, opcodes); + } + else + stream << "CFLUSH"; + break; + + case 0x28: + util::stream_format(stream, "%-8s", util::string_format("TST%c", "W?HB"[op & 0x03])); + dasm_src(stream, pc, opcodes); + break; + + case 0x2c: + if (!BIT(op, 1)) + { + util::stream_format(stream, "%-8s", "CALL"); + dasm_ea(stream, pc, opcodes); + stream << ","; + dasm_ea(stream, pc, opcodes); + flags |= STEP_OVER; + } + else if (!BIT(op, 0)) + { + stream << "BPT"; + flags |= STEP_OVER; + } + else + { + stream << "WAIT"; // (privileged) + } + break; + + case 0x30: + if (!BIT(op, 1)) + flags = dasm_30xx(stream, pc, opcodes); + else if (!BIT(op, 0)) + { + util::stream_format(stream, "%-8s0x%08x", "SPOP", swapendian_int32(opcodes.r32(pc))); + pc += 4; + } + else + { + util::stream_format(stream, "%-8s0x%08x,", "SPOPWS", swapendian_int32(opcodes.r32(pc))); + pc += 4; + dasm_dst(stream, pc, opcodes); + } + break; + + case 0x34: + if (!BIT(op, 1)) + { + util::stream_format(stream, "%-8s", "JSB"); + dasm_ea(stream, pc, opcodes); + } + else + { + util::stream_format(stream, "%-8s", BIT(op, 0) ? "BSBB" : "BSBH"); + dasm_bdisp(stream, pc, opcodes, BIT(op, 0)); + } + flags |= STEP_OVER; + break; + + case 0x38: + util::stream_format(stream, "%-8s", util::string_format("BIT%c", "W?HB"[op & 0x03])); + dasm_src(stream, pc, opcodes); + stream << ","; + dasm_src(stream, pc, opcodes); + break; + + case 0x3c: + util::stream_format(stream, "%-8s", util::string_format("CMP%c", "W?HB"[op & 0x03])); + dasm_src(stream, pc, opcodes); + stream << ","; + dasm_src(stream, pc, opcodes); + break; + + case 0x40: + if (!BIT(op, 1)) + { + stream << "RGEQ"; + flags |= STEP_OUT; + } + else + { + util::stream_format(stream, "%-8s", BIT(op, 0) ? "BGEB" : "BGEH"); + dasm_bdisp(stream, pc, opcodes, BIT(op, 0)); + } + break; + + case 0x44: case 0x54: + if (!BIT(op, 1)) + { + stream << "RGTR"; + if (BIT(op, 4)) + stream << "U"; + flags |= STEP_OUT; + } + else + { + if (BIT(op, 4)) + util::stream_format(stream, "%-8s", BIT(op, 0) ? "BGUB" : "BGUH"); + else + util::stream_format(stream, "%-8s", BIT(op, 0) ? "BGB" : "BGH"); + dasm_bdisp(stream, pc, opcodes, BIT(op, 0)); + } + break; + + case 0x48: + if (!BIT(op, 1)) + { + stream << "RLSS"; + flags |= STEP_OUT; + } + else + { + util::stream_format(stream, "%-8s", BIT(op, 0) ? "BLB" : "BLH"); + dasm_bdisp(stream, pc, opcodes, BIT(op, 0)); + } + break; + + case 0x4c: case 0x5c: + if (!BIT(op, 1)) + { + stream << "RLEQ"; + if (BIT(op, 4)) + stream << "U"; + flags |= STEP_OUT; + } + else + { + if (BIT(op, 4)) + util::stream_format(stream, "%-8s", BIT(op, 0) ? "BLEUB" : "BLEUH"); + else + util::stream_format(stream, "%-8s", BIT(op, 0) ? "BLEB" : "BLEH"); + dasm_bdisp(stream, pc, opcodes, BIT(op, 0)); + } + break; + + case 0x50: + if (!BIT(op, 1)) + { + stream << "RCC"; + flags |= STEP_OUT; + } + else + { + util::stream_format(stream, "%-8s", BIT(op, 0) ? "BCC" : "BCC"); + dasm_bdisp(stream, pc, opcodes, BIT(op, 0)); + } + break; + + case 0x58: + if (!BIT(op, 1)) + { + stream << "RCS"; + flags |= STEP_OUT; + } + else + { + util::stream_format(stream, "%-8s", BIT(op, 0) ? "BCSB" : "BCSH"); + dasm_bdisp(stream, pc, opcodes, BIT(op, 0)); + } + break; + + case 0x60: + if (!BIT(op, 1)) + { + stream << "RVS"; + flags |= STEP_OUT; + } + else + { + util::stream_format(stream, "%-8s", BIT(op, 0) ? "BVCB" : "BVCH"); + dasm_bdisp(stream, pc, opcodes, BIT(op, 0)); + } + break; + + case 0x64: case 0x74: + if (!BIT(op, 1)) + { + stream << "RNEQ"; + if (!BIT(op, 4)) + stream << "U"; + flags |= STEP_OUT; + } + else + { + util::stream_format(stream, "%-8s", BIT(op, 0) ? "BNEB" : "BNEH"); + dasm_bdisp(stream, pc, opcodes, BIT(op, 0)); + } + break; + + case 0x68: + if (!BIT(op, 1)) + { + stream << "RVS"; + flags |= STEP_OUT; + } + else + { + util::stream_format(stream, "%-8s", BIT(op, 0) ? "BVSB" : "BVSH"); + dasm_bdisp(stream, pc, opcodes, BIT(op, 0)); + } + break; + + case 0x6c: case 0x7c: + if (!BIT(op, 1)) + { + stream << "REQL"; + if (!BIT(op, 4)) + stream << "U"; + flags |= STEP_OUT; + } + else + { + util::stream_format(stream, "%-8s", BIT(op, 0) ? "BEB" : "BEH"); + dasm_bdisp(stream, pc, opcodes, BIT(op, 0)); + } + break; + + case 0x70: + if (!BIT(op, 1)) + stream << "NOP"; + else if (BIT(op, 0)) + util::stream_format(stream, "%-8s0x%02x", "NOP2", opcodes.r8(pc++)); + else + { + util::stream_format(stream, "%-8s0x%04x", "NOP3", swapendian_int16(opcodes.r16(pc))); + pc += 2; + } + break; + + case 0x78: + if (!BIT(op, 1)) + { + stream << "RSB"; + flags |= STEP_OUT; + } + else + { + util::stream_format(stream, "%-8s", BIT(op, 0) ? "BRB" : "BRH"); + dasm_bdisp(stream, pc, opcodes, BIT(op, 0)); + } + break; + + case 0x80: + util::stream_format(stream, "%-8s", util::string_format("CLR%c", "W?HB"[op & 0x03])); + dasm_dst(stream, pc, opcodes); + break; + + case 0x84: + util::stream_format(stream, "%-8s", util::string_format("MOV%c", "W?HB"[op & 0x03])); + dasm_src(stream, pc, opcodes); + stream << ","; + dasm_dst(stream, pc, opcodes); + break; + + case 0x88: + util::stream_format(stream, "%-8s", util::string_format("MCOM%c", "W?HB"[op & 0x03])); + dasm_src(stream, pc, opcodes); + stream << ","; + dasm_dst(stream, pc, opcodes); + break; + + case 0x8c: + util::stream_format(stream, "%-8s", util::string_format("MNEG%c", "W?HB"[op & 0x03])); + dasm_src(stream, pc, opcodes); + stream << ","; + dasm_dst(stream, pc, opcodes); + break; + + case 0x90: + util::stream_format(stream, "%-8s", util::string_format("INC%c", "W?HB"[op & 0x03])); + dasm_dst(stream, pc, opcodes); + break; + + case 0x94: + util::stream_format(stream, "%-8s", util::string_format("DEC%c", "W?HB"[op & 0x03])); + dasm_dst(stream, pc, opcodes); + break; + + case 0x9c: case 0xdc: + util::stream_format(stream, "%-8s", util::string_format("ADD%c%d", "W?HB"[op & 0x03], BIT(op, 6) ? 3 : 2)); + dasm_src(stream, pc, opcodes); + if (BIT(op, 6)) + { + stream << ","; + dasm_src(stream, pc, opcodes); + } + stream << ","; + dasm_dst(stream, pc, opcodes); + break; + + case 0xa0: + util::stream_format(stream, "%-8s", "PUSHW"); + dasm_srcw(stream, pc, opcodes); + break; + + case 0xa4: case 0xe4: + util::stream_format(stream, "%-8s", util::string_format("MOD%c%d", "W?HB"[op & 0x03], BIT(op, 6) ? 3 : 2)); + dasm_src(stream, pc, opcodes); + if (BIT(op, 6)) + { + stream << ","; + dasm_src(stream, pc, opcodes); + } + stream << ","; + dasm_dst(stream, pc, opcodes); + break; + + case 0xa8: case 0xe8: + util::stream_format(stream, "%-8s", util::string_format("MUL%c%d", "W?HB"[op & 0x03], BIT(op, 6) ? 3 : 2)); + dasm_src(stream, pc, opcodes); + if (BIT(op, 6)) + { + stream << ","; + dasm_src(stream, pc, opcodes); + } + stream << ","; + dasm_dst(stream, pc, opcodes); + break; + + case 0xac: case 0xec: + util::stream_format(stream, "%-8s", util::string_format("DIV%c%d", "W?HB"[op & 0x03], BIT(op, 6) ? 3 : 2)); + dasm_src(stream, pc, opcodes); + if (BIT(op, 6)) + { + stream << ","; + dasm_src(stream, pc, opcodes); + } + stream << ","; + dasm_dst(stream, pc, opcodes); + break; + + case 0xb0: case 0xf0: + util::stream_format(stream, "%-8s", util::string_format("OR%c%d", "W?HB"[op & 0x03], BIT(op, 6) ? 3 : 2)); + dasm_src(stream, pc, opcodes); + if (BIT(op, 6)) + { + stream << ","; + dasm_src(stream, pc, opcodes); + } + stream << ","; + dasm_dst(stream, pc, opcodes); + break; + + case 0xb4: case 0xf4: + util::stream_format(stream, "%-8s", util::string_format("XOR%c%d", "W?HB"[op & 0x03], BIT(op, 6) ? 3 : 2)); + dasm_src(stream, pc, opcodes); + if (BIT(op, 6)) + { + stream << ","; + dasm_src(stream, pc, opcodes); + } + stream << ","; + dasm_dst(stream, pc, opcodes); + break; + + case 0xb8: case 0xf8: + util::stream_format(stream, "%-8s", util::string_format("AND%c%d", "W?HB"[op & 0x03], BIT(op, 6) ? 3 : 2)); + dasm_src(stream, pc, opcodes); + if (BIT(op, 6)) + { + stream << ","; + dasm_src(stream, pc, opcodes); + } + stream << ","; + dasm_dst(stream, pc, opcodes); + break; + + case 0xbc: case 0xfc: + util::stream_format(stream, "%-8s", util::string_format("SUB%c%d", "W?HB"[op & 0x03], BIT(op, 6) ? 3 : 2)); + dasm_src(stream, pc, opcodes); + if (BIT(op, 6)) + { + stream << ","; + dasm_src(stream, pc, opcodes); + } + stream << ","; + dasm_dst(stream, pc, opcodes); + break; + + case 0xc0: case 0xc4: case 0xd0: case 0xd4: + util::stream_format(stream, "%-8s", util::string_format("%c%cS%c3", BIT(op, 4) ? 'L' : 'A', BIT(op, 2) ? 'R' : 'L', "W?HB"[op & 0x03])); + dasm_src(stream, pc, opcodes); + stream << ","; + dasm_src(stream, pc, opcodes); + stream << ","; + dasm_dst(stream, pc, opcodes); + break; + + case 0xc8: + util::stream_format(stream, "%-8s", util::string_format("INS%c3", "W?HB"[op & 0x03])); + dasm_src(stream, pc, opcodes); + stream << ","; + dasm_src(stream, pc, opcodes); + stream << ","; + dasm_src(stream, pc, opcodes); + stream << ","; + dasm_dst(stream, pc, opcodes); + break; + + case 0xcc: + util::stream_format(stream, "%-8s", util::string_format("EXT%c3", "W?HB"[op & 0x03])); + dasm_src(stream, pc, opcodes); + stream << ","; + dasm_src(stream, pc, opcodes); + stream << ","; + dasm_src(stream, pc, opcodes); + stream << ","; + dasm_dst(stream, pc, opcodes); + break; + + case 0xd8: + util::stream_format(stream, "%-8s", "ROTW"); + dasm_src(stream, pc, opcodes); + stream << ","; + dasm_src(stream, pc, opcodes); + stream << ","; + dasm_dst(stream, pc, opcodes); + break; + + case 0xe0: + util::stream_format(stream, "%-8s", "PUSHAW"); + dasm_ea(stream, pc, opcodes); + break; + } + + return flags | ((pc - ppc) & LENGTHMASK); +} diff --git a/src/devices/cpu/we32000/we32100d.h b/src/devices/cpu/we32000/we32100d.h new file mode 100644 index 00000000000..1c287d85702 --- /dev/null +++ b/src/devices/cpu/we32000/we32100d.h @@ -0,0 +1,36 @@ +// license:BSD-3-Clause +// copyright-holders:AJR + +#ifndef MAME_CPU_WE32000_WE32100D_H +#define MAME_CPU_WE32000_WE32100D_H + +#pragma once + +class we32100_disassembler : public util::disasm_interface +{ +public: + // construction/destruction + we32100_disassembler(); + +protected: + // disassembler overrides + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const s_rnames[16]; + + // internal helpers + void format_signed(std::ostream &stream, s32 x); + void dasm_am(std::ostream &stream, offs_t &pc, const data_buffer &opcodes, u8 n, bool dst); + void dasm_src(std::ostream &stream, offs_t &pc, const data_buffer &opcodes); + void dasm_srcw(std::ostream &stream, offs_t &pc, const data_buffer &opcodes); + void dasm_dst(std::ostream &stream, offs_t &pc, const data_buffer &opcodes); + void dasm_dstw(std::ostream &stream, offs_t &pc, const data_buffer &opcodes); + void dasm_ea(std::ostream &stream, offs_t &pc, const data_buffer &opcodes); + void dasm_sr(std::ostream &stream, offs_t &pc, const data_buffer &opcodes); + void dasm_bdisp(std::ostream &stream, offs_t &pc, const data_buffer &opcodes, bool byte); + offs_t dasm_30xx(std::ostream &stream, offs_t &pc, const data_buffer &opcodes); +}; + +#endif // MAME_CPU_WE32000_WE32100D_H diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 852d5ff126c..c8a442d5213 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -2971,6 +2971,11 @@ atrwild atricmon atrbonpk +@source:att3b2.cpp +3b2_300 // +3b2_310 // +3b2_400 // + @source:att4425.cpp att4425 // diff --git a/src/mame/mess.flt b/src/mame/mess.flt index 37fe0f6bd21..875b99e6db8 100644 --- a/src/mame/mess.flt +++ b/src/mame/mess.flt @@ -83,6 +83,7 @@ atarist.cpp atm.cpp atom.cpp atpci.cpp +att3b2.cpp att4425.cpp att610.cpp att630.cpp diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp index fd8e932658c..6e899c4f88b 100644 --- a/src/tools/unidasm.cpp +++ b/src/tools/unidasm.cpp @@ -160,6 +160,7 @@ using util::BIT; #include "cpu/v60/v60d.h" #include "cpu/v810/v810dasm.h" #include "cpu/vt50/vt50dasm.h" +#include "cpu/we32000/we32100d.h" #include "cpu/z180/z180dasm.h" #include "cpu/z8/z8dasm.h" #include "cpu/z80/z80dasm.h" @@ -528,6 +529,7 @@ static const dasm_table_entry dasm_table[] = { "v810", le, 0, []() -> util::disasm_interface * { return new v810_disassembler; } }, { "vt50", le, 0, []() -> util::disasm_interface * { return new vt50_disassembler; } }, { "vt52", le, 0, []() -> util::disasm_interface * { return new vt52_disassembler; } }, + { "we32100", be, 0, []() -> util::disasm_interface * { return new we32100_disassembler; } }, { "x86_16", le, 0, []() -> util::disasm_interface * { i386_unidasm.mode = 16; return new i386_disassembler(&i386_unidasm); } }, { "x86_32", le, 0, []() -> util::disasm_interface * { i386_unidasm.mode = 32; return new i386_disassembler(&i386_unidasm); } }, { "x86_64", le, 0, []() -> util::disasm_interface * { i386_unidasm.mode = 64; return new i386_disassembler(&i386_unidasm); } },