Add new disassembler for WE32100 architecture

New machines marked as NOT_WORKING
----------------------------------
AT&T 3B2/300 [Bitsavers]

New clones marked as NOT_WORKING
--------------------------------
AT&T 3B2/310 [Bitsavers]
AT&T 3B2/400 [Bitsavers]
This commit is contained in:
AJR 2019-12-30 19:15:31 -05:00
parent b052050f3c
commit f48f57ef81
9 changed files with 1094 additions and 0 deletions

View File

@ -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

View File

@ -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",

View File

@ -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<util::disasm_interface> we32100_device::create_disassembler()
{
return std::make_unique<we32100_disassembler>();
}
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;
}
}

View File

@ -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<util::disasm_interface> 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

View File

@ -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 &params)
{
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);
}

View File

@ -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 &params) 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

View File

@ -2971,6 +2971,11 @@ atrwild
atricmon
atrbonpk
@source:att3b2.cpp
3b2_300 //
3b2_310 //
3b2_400 //
@source:att4425.cpp
att4425 //

View File

@ -83,6 +83,7 @@ atarist.cpp
atm.cpp
atom.cpp
atpci.cpp
att3b2.cpp
att4425.cpp
att610.cpp
att630.cpp

View File

@ -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); } },