From 14c4dcc643d9c735abeceab7ccaf2a0cf8a7541f Mon Sep 17 00:00:00 2001 From: AJR Date: Sat, 28 Dec 2019 12:35:20 -0500 Subject: Add new disassembler for PACE architecture New machines marked as NOT_WORKING ---------------------------------- unknown INS8900 Multibus card (980305652) [Bitsavers] --- scripts/src/cpu.lua | 17 ++ scripts/target/mame/mess.lua | 2 + src/devices/cpu/pace/pace.cpp | 206 ++++++++++++++++++++++++ src/devices/cpu/pace/pace.h | 122 +++++++++++++++ src/devices/cpu/pace/pacedasm.cpp | 321 ++++++++++++++++++++++++++++++++++++++ src/devices/cpu/pace/pacedasm.h | 36 +++++ src/mame/drivers/ns5652.cpp | 59 +++++++ src/mame/mame.lst | 3 + src/mame/mess.flt | 1 + src/tools/unidasm.cpp | 2 + 10 files changed, 769 insertions(+) create mode 100644 src/devices/cpu/pace/pace.cpp create mode 100644 src/devices/cpu/pace/pace.h create mode 100644 src/devices/cpu/pace/pacedasm.cpp create mode 100644 src/devices/cpu/pace/pacedasm.h create mode 100644 src/mame/drivers/ns5652.cpp diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua index f027f0aa329..2a83be1f0ad 100644 --- a/scripts/src/cpu.lua +++ b/scripts/src/cpu.lua @@ -3014,3 +3014,20 @@ if (CPUS["VT50"]~=null or _OPTIONS["with-tools"]) then table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/vt50/vt50dasm.cpp") table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/vt50/vt50dasm.h") end + +-------------------------------------------------- +-- National Semiconductor PACE/INS8900 +--@src/devices/cpu/pace/pace.h,CPUS["PACE"] = true +-------------------------------------------------- + +if (CPUS["PACE"]~=null) then + files { + MAME_DIR .. "src/devices/cpu/pace/pace.cpp", + MAME_DIR .. "src/devices/cpu/pace/pace.h", + } +end + +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 diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index f112b19fc9d..fc5bf321b4b 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -149,6 +149,7 @@ CPUS["CR16B"] = true CPUS["FR"] = true CPUS["DSP56000"] = true CPUS["VT50"] = true +CPUS["PACE"] = true -------------------------------------------------- -- specify available sound cores; some of these are @@ -2787,6 +2788,7 @@ files { createMESSProjects(_target, _subtarget, "natsemi") files { MAME_DIR .. "src/mame/drivers/hh_cop400.cpp", + MAME_DIR .. "src/mame/drivers/ns5652.cpp", } createMESSProjects(_target, _subtarget, "ncd") diff --git a/src/devices/cpu/pace/pace.cpp b/src/devices/cpu/pace/pace.cpp new file mode 100644 index 00000000000..bc0e6f5b62a --- /dev/null +++ b/src/devices/cpu/pace/pace.cpp @@ -0,0 +1,206 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + National Semiconductor PACE/INS8900 + + The IPC-16A PACE (Processing and Control Element) was one of the first + commercially available 16-bit microprocessors. It was a successor to + the multiple-chip IMP-16 processor and implemented a similar four- + accumulator architecture in a single PMOS LSI package using internal + microcode. PACE requires two clock inputs with non-overlapping low + phases and frequencies between 1.25 and 1.538 MHz. + + The standard machine cycle takes 4 clock periods (and the shortest + instructions take 4 cycles each), though cycles can be stretched by + asserting the EXTEND pin. Six interrupts are available, one triggered + only by internal stack full/empty conditions; the nonmaskable level 0 + interrupt is intended primarily for debugging. The on-chip 10-level + LIFO stack may hold both return addresses and register data. All + instructions are single-word. + + INS8900 was a NMOS reimplementation of PACE which takes a single-phase + clock and allows up to 2 MHz operation. It has different power supply + requirements, but is functionally identical. + +***************************************************************************/ + +#include "emu.h" +#include "pace.h" +#include "pacedasm.h" + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +// device type definition +DEFINE_DEVICE_TYPE(INS8900, ins8900_device, "ins8900", "National Semiconductor INS8900") + + +//************************************************************************** +// DEVICE CONSTRUCTION AND INITIALIZATION +//************************************************************************** + +//------------------------------------------------- +// pace_device - constructor +//------------------------------------------------- + +pace_device::pace_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) + : cpu_device(mconfig, type, tag, owner, clock) + , m_space_config("program", ENDIANNESS_LITTLE, 16, 16, -1) + , m_space(nullptr) + , m_inst_cache(nullptr) + , m_jc_callback{{*this}, {*this}, {*this}} + , m_flag_callback{{*this}, {*this}, {*this}, {*this}} + , m_icount(0) + , m_pc(0) + , m_fr(0xffff) + , m_ac{0, 0, 0, 0} + , m_sp(0) + , m_stk{0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +{ +} + + +//------------------------------------------------- +// ins8900_device - constructor +//------------------------------------------------- + +ins8900_device::ins8900_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : pace_device(mconfig, INS8900, tag, owner, clock) +{ +} + + +//------------------------------------------------- +// memory_space_config - return a vector of +// configuration structures for memory spaces +//------------------------------------------------- + +device_memory_interface::space_config_vector pace_device::memory_space_config() const +{ + return space_config_vector { + std::make_pair(AS_PROGRAM, &m_space_config) + }; +} + + +//------------------------------------------------- +// device_resolve_objects - resolve objects that +// may be needed for other devices to set +// initial conditions at start time +//------------------------------------------------- + +void pace_device::device_resolve_objects() +{ + // resolve callbacks + for (auto &cb : m_jc_callback) + cb.resolve_safe(0); + for (auto &cb : m_flag_callback) + cb.resolve_safe(); +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void pace_device::device_start() +{ + // get memory spaces + m_space = &space(AS_PROGRAM); + m_inst_cache = m_space->cache<1, -1, ENDIANNESS_LITTLE>(); + + set_icountptr(m_icount); + + // debug state registration + state_add(PACE_PC, "PC", m_pc); + state_add(STATE_GENPC, "GENPC", m_pc).noshow(); + state_add(STATE_GENPCBASE, "GENPCBASE", m_pc).noshow(); + state_add(PACE_FR, "FR", [this]() { return m_fr; }, [this](u16 data) { fr_w(data); }); + state_add(STATE_GENFLAGS, "GENFLAGS", m_fr).noshow(); + for (int i = 0; i < 4; i++) + state_add(PACE_AC0 + i, string_format("AC%d", i).c_str(), m_ac[i]); + state_add(PACE_SP, "SP", + [this]() { return m_sp; }, + [this](u8 data) { m_sp = data < 10 ? data : BIT(data, 0) ? 9 : 0; }).mask(0xf); + for (int i = 0; i < 10; i++) + state_add(PACE_STK0 + i, string_format("STK%d", i).c_str(), m_stk[i]); + + // save states + save_item(NAME(m_pc)); + save_item(NAME(m_fr)); + save_item(NAME(m_ac)); + save_item(NAME(m_sp)); + save_item(NAME(m_stk)); +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void pace_device::device_reset() +{ + m_pc = 0; + fr_w(0); + m_sp = 0; +} + + +//------------------------------------------------- +// create_disassembler - factory method for +// disassembling program code +//------------------------------------------------- + +std::unique_ptr pace_device::create_disassembler() +{ + return std::make_unique(); +} + + +//************************************************************************** +// I/O LINES, INTERRUPTS AND FLAGS +//************************************************************************** + +//------------------------------------------------- +// fr_w - update the flag register +//------------------------------------------------- + +void pace_device::fr_w(u16 data) +{ + for (int i = 0; i < 4; i++) + if (BIT(data, 11 + i) != BIT(m_fr, 11 + i)) + m_flag_callback[i](BIT(data, 11 + i)); + + // Bits 0 and 15 are always logic 1 + m_fr = data | 0x8001; +} + + +//------------------------------------------------- +// execute_set_input - +//------------------------------------------------- + +void pace_device::execute_set_input(int irqline, int state) +{ + // TODO +} + + +//************************************************************************** +// PROGRAM EXECUTION +//************************************************************************** + +//------------------------------------------------- +// execute_run - +//------------------------------------------------- + +void pace_device::execute_run() +{ + // TODO + + debugger_instruction_hook(m_pc); + m_icount = 0; +} diff --git a/src/devices/cpu/pace/pace.h b/src/devices/cpu/pace/pace.h new file mode 100644 index 00000000000..60ba9766768 --- /dev/null +++ b/src/devices/cpu/pace/pace.h @@ -0,0 +1,122 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + National Semiconductor PACE/INS8900 + +**************************************************************************** + _____________ + D04 1 | | 40 D05 + D03 2 | | 39 D06 + D02 3 | | 38 D07 + D01 4 | | 37 D08 + D00 5 | | 36 D09 + IDS 6 | | 35 D10 + ODS 7 | | 34 D11 + NADS 8 | | 33 D12 + NHALT 9 | | 32 D13 + CONTIN 10 | IPC-16A | 31 D14 + JC14 11 | INS8900 | 30 D15 + JC15 12 | | 29 Vgg/Vdd* + JC13 13 | | 28 BPS + NIR5 14 | | 27 EXTEND + NIR4 15 | | 26 NINIT + NIR3 16 | | 25 CLK/Vcc* + NIR2 17 | | 24 NCLK/CLKX + F11 18 | | 23 Vbb* + F12 19 | | 22 F14 + Vss* 20 |_____________| 21 F13 + + * For PACE (IPC-16A): Vss = +5V, Vbb = +8V, Vgg = -12V + * For INS8900: Vss = GND, Vbb = -8V, Vcc = +5V, Vdd = +12V + +***************************************************************************/ + +#ifndef MAME_CPU_PACE_PACE_H +#define MAME_CPU_PACE_PACE_H + +#pragma once + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> pace_device + +class pace_device : public cpu_device +{ +public: + // register enumeration + enum { + PACE_PC, + PACE_FR, + PACE_AC0, PACE_AC1, PACE_AC2, PACE_AC3, + PACE_SP, + PACE_STK0, PACE_STK1, PACE_STK2, PACE_STK3, PACE_STK4, + PACE_STK5, PACE_STK6, PACE_STK7, PACE_STK8, PACE_STK9 + }; + + // callback configuration + auto jc13_callback() { return m_jc_callback[0].bind(); } + auto jc14_callback() { return m_jc_callback[1].bind(); } + auto jc15_callback() { return m_jc_callback[2].bind(); } + auto f11_callback() { return m_flag_callback[0].bind(); } + auto f12_callback() { return m_flag_callback[1].bind(); } + auto f13_callback() { return m_flag_callback[2].bind(); } + auto f14_callback() { return m_flag_callback[3].bind(); } + +protected: + // construction/destruction + pace_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); + + // device-specific overrides + virtual void device_resolve_objects() override; + 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 irqline, 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; + +private: + // internal helpers + void fr_w(u16 data); + + // address space and cache + address_space_config m_space_config; + address_space *m_space; + memory_access_cache<1, -1, ENDIANNESS_LITTLE> *m_inst_cache; + + // callback objects + devcb_read_line m_jc_callback[3]; + devcb_write_line m_flag_callback[4]; + + // execution state + s32 m_icount; + u16 m_pc; + u16 m_fr; + u16 m_ac[4]; + u8 m_sp; + u16 m_stk[10]; +}; + +// ======================> ins8900_device + +class ins8900_device : public pace_device +{ +public: + // device type constructor + ins8900_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); +}; + +// device type declarations +DECLARE_DEVICE_TYPE(INS8900, ins8900_device) + +#endif // MAME_CPU_PACE_PACE_H diff --git a/src/devices/cpu/pace/pacedasm.cpp b/src/devices/cpu/pace/pacedasm.cpp new file mode 100644 index 00000000000..6ab93f8f75d --- /dev/null +++ b/src/devices/cpu/pace/pacedasm.cpp @@ -0,0 +1,321 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + National Semiconductor PACE (IPC-16A, INS8900) disassembler + + This uses the same basic instruction set as IMP-16, but the binary + encoding is not compatible. + +***************************************************************************/ + +#include "emu.h" +#include "pacedasm.h" + + +//************************************************************************** +// PACE DISASSEMBLER +//************************************************************************** + +pace_disassembler::pace_disassembler() + : util::disasm_interface() +{ +} + +u32 pace_disassembler::opcode_alignment() const +{ + return 1; +} + +const char *const pace_disassembler::s_cc[16] = { + "STFL", // stack full + "REQ0", // AC0 equals zero + "PSIGN", // AC0 has positive sign + "BIT0", // AC0 has bit 0 set + "BIT1", // AC0 has bit 1 set + "NREQ0", // AC0 does not equal zero + "BIT2", // AC0 has bit 2 set + "CONTIN", // CONTIN input is high + "LINK", // LINK is set + "IEN", // IEN is set + "CARRY", // CARRY is set + "NSIGN", // AC0 has negative sign + "OV", // OV is set + "JC13", // JC13 is high + "JC14", // JC14 is high + "JC15" // JC15 is high +}; + +const char *const pace_disassembler::s_flags[16] = { + "F0", // does not exist in FR + "IE1", + "IE2", + "IE3", + "IE4", + "IE5", + "OVF", + "CRY", + "LINK", + "IEN", + "BYTE", + "F11", + "F12", + "F13", + "F14", + "F15" // does not exist in FR, but used to reset IE0 after level 0 interrupt +}; + +void pace_disassembler::format_addr(std::ostream &stream, u16 addr) +{ + if (addr >= 0x1000) + stream << "0"; + util::stream_format(stream, "%04X", addr); +} + +void pace_disassembler::format_disp(std::ostream &stream, u8 disp) +{ + if (disp >= 0x80) + { + stream << "-"; + disp = 0x100 - disp; + } + if (disp < 0x0a) + util::stream_format(stream, "%d", disp); + else + util::stream_format(stream, "0%X", disp); +} + +void pace_disassembler::format_ea(std::ostream &stream, u16 pc, u16 inst) +{ + if ((inst & 0x0300) == 0x0000) + { + // 0000–00FF or 0000–007F, FF80–FFFF depending on BPS input + if ((inst & 0x00ff) >= 0x10) + stream << "0"; + util::stream_format(stream, "%02X", inst & 0x00ff); + } + else if ((inst & 0x0300) == 0x0100) + format_addr(stream, pc + 1 + s8(inst & 0x00ff)); + else + { + format_disp(stream, inst & 0x00ff); + util::stream_format(stream, "(AC%d)", (inst & 0x0300) >> 8); + } +} + +offs_t pace_disassembler::disassemble(std::ostream &stream, offs_t pc, const pace_disassembler::data_buffer &opcodes, const pace_disassembler::data_buffer ¶ms) +{ + u16 inst = opcodes.r16(pc); + + switch (inst & 0xfc00) + { + case 0x0000: + stream << "HALT"; + return 1; + + case 0x0400: + util::stream_format(stream, "%-8sAC%d", "CFR", (inst & 0x0300) >> 8); + return 1; + + case 0x0800: + util::stream_format(stream, "%-8sAC%d", "CRF", (inst & 0x0300) >> 8); + return 1; + + case 0x0c00: + stream << "PUSHF"; + return 1; + + case 0x1000: + stream << "PULLF"; + return 1; + + case 0x1400: + util::stream_format(stream, "%-8s", "JSR"); + format_ea(stream, pc, inst); + return 1 | STEP_OVER; + + case 0x1800: + util::stream_format(stream, "%-8s", "JMP"); + format_ea(stream, pc, inst); + return 1; + + case 0x1c00: + util::stream_format(stream, "%-8sAC%d", "XCHRS", (inst & 0x0300) >> 8); + return 1; + + case 0x2000: + util::stream_format(stream, "%-8sAC%d,%d,%d", "ROL", (inst & 0x0300) >> 8, (inst & 0x00fe) >> 1, inst & 0x0001); + return 1; + + case 0x2400: + util::stream_format(stream, "%-8sAC%d,%d,%d", "ROR", (inst & 0x0300) >> 8, (inst & 0x00fe) >> 1, inst & 0x0001); + return 1; + + case 0x2800: + util::stream_format(stream, "%-8sAC%d,%d,%d", "SHL", (inst & 0x0300) >> 8, (inst & 0x00fe) >> 1, inst & 0x0001); + return 1; + + case 0x2c00: + util::stream_format(stream, "%-8sAC%d,%d,%d", "SHR", (inst & 0x0300) >> 8, (inst & 0x00fe) >> 1, inst & 0x0001); + return 1; + + case 0x3000: case 0x3400: case 0x3800: case 0x3c00: + util::stream_format(stream, "%-8s%s", BIT(inst, 7) ? "SFLG" : "PFLG", s_flags[(inst & 0x0f00) >> 8]); + return 1; + + case 0x4000: case 0x4400: case 0x4800: case 0x4c00: + util::stream_format(stream, "%-8s%s,", "BOC", s_cc[(inst & 0x0f00) >> 8]); + format_addr(stream, pc + 1 + s8(inst & 0x00ff)); + return 1; + + case 0x5000: + util::stream_format(stream, "%-8sAC%d,", "LI", (inst & 0x0300) >> 8); + format_disp(stream, inst & 0x00ff); + return 1; + + case 0x5400: + util::stream_format(stream, "%-8sAC%d,AC%d", "RAND", (inst & 0x00c0) >> 6, (inst & 0x0300) >> 8); + return 1; + + case 0x5800: + util::stream_format(stream, "%-8sAC%d,AC%d", "RXOR", (inst & 0x00c0) >> 6, (inst & 0x0300) >> 8); + return 1; + + case 0x5c00: + if ((inst & 0x0300) >> 2 == (inst & 0x00c0)) + stream << "NOP"; + else + util::stream_format(stream, "%-8sAC%d,AC%d", "RCPY", (inst & 0x00c0) >> 6, (inst & 0x0300) >> 8); + return 1; + + case 0x6000: + util::stream_format(stream, "%-8sAC%d", "PUSH", (inst & 0x0300) >> 8); + return 1; + + case 0x6400: + util::stream_format(stream, "%-8sAC%d", "PULL", (inst & 0x0300) >> 8); + return 1; + + case 0x6800: + util::stream_format(stream, "%-8sAC%d,AC%d", "RADD", (inst & 0x00c0) >> 6, (inst & 0x0300) >> 8); + return 1; + + case 0x6c00: + util::stream_format(stream, "%-8sAC%d,AC%d", "RXCH", (inst & 0x00c0) >> 6, (inst & 0x0300) >> 8); + return 1; + + case 0x7000: + util::stream_format(stream, "%-8sAC%d,", "CAI", (inst & 0x0300) >> 8); + format_disp(stream, inst & 0x00ff); + return 1; + + case 0x7400: + util::stream_format(stream, "%-8sAC%d,AC%d", "RADC", (inst & 0x00c0) >> 6, (inst & 0x0300) >> 8); + return 1; + + case 0x7800: + util::stream_format(stream, "%-8sAC%d,", "AISZ", (inst & 0x0300) >> 8); + format_disp(stream, inst & 0x00ff); + return 1 | STEP_OVER; + + case 0x7c00: + util::stream_format(stream, "%-8s", "RTI"); + format_disp(stream, inst & 0x00ff); + return 1 | STEP_OUT; + + case 0x8000: + util::stream_format(stream, "%-8s", "RTS"); + format_disp(stream, inst & 0x00ff); + return 1 | STEP_OUT; + + case 0x8800: + util::stream_format(stream, "%-8sAC0,", "DECA"); + format_ea(stream, pc, inst); + return 1; + + case 0x8c00: + util::stream_format(stream, "%-8s", "ISZ"); + format_ea(stream, pc, inst); + return 1 | STEP_OVER; + + case 0x9000: + util::stream_format(stream, "%-8sAC0,", "SUBB"); + format_ea(stream, pc, inst); + return 1; + + case 0x9400: + util::stream_format(stream, "%-8s@", "JSR"); + format_ea(stream, pc, inst); + return 1 | STEP_OVER; + + case 0x9800: + util::stream_format(stream, "%-8s@", "JMP"); + format_ea(stream, pc, inst); + return 1; + + case 0x9c00: + util::stream_format(stream, "%-8sAC0,", "SKG"); + format_ea(stream, pc, inst); + return 1 | STEP_OVER; + + case 0xa000: + util::stream_format(stream, "%-8sAC0,@", "LD"); + format_ea(stream, pc, inst); + return 1; + + case 0xa400: + util::stream_format(stream, "%-8sAC0,", "OR"); + format_ea(stream, pc, inst); + return 1; + + case 0xa800: + util::stream_format(stream, "%-8sAC0,", "AND"); + format_ea(stream, pc, inst); + return 1; + + case 0xac00: + util::stream_format(stream, "%-8s", "DSZ"); + format_ea(stream, pc, inst); + return 1 | STEP_OVER; + + case 0xb000: + util::stream_format(stream, "%-8sAC0,@", "ST"); + format_ea(stream, pc, inst); + return 1; + + case 0xb800: + util::stream_format(stream, "%-8sAC0,", "SKAZ"); + format_ea(stream, pc, inst); + return 1 | STEP_OVER; + + case 0xbc00: + util::stream_format(stream, "%-8sAC0,", "LSEX"); + format_ea(stream, pc, inst); + return 1; + + case 0xc000: case 0xc400: case 0xc800: case 0xcc00: + util::stream_format(stream, "%-8sAC%d,", "LD", (inst & 0x0c00) >> 10); + format_ea(stream, pc, inst); + return 1; + + case 0xd000: case 0xd400: case 0xd800: case 0xdc00: + util::stream_format(stream, "%-8sAC%d,", "ST", (inst & 0x0c00) >> 10); + format_ea(stream, pc, inst); + return 1; + + case 0xe000: case 0xe400: case 0xe800: case 0xec00: + util::stream_format(stream, "%-8sAC%d,", "ADD", (inst & 0x0c00) >> 10); + format_ea(stream, pc, inst); + return 1; + + case 0xf000: case 0xf400: case 0xf800: case 0xfc00: + util::stream_format(stream, "%-8sAC%d,", "SKNE", (inst & 0x0c00) >> 10); + format_ea(stream, pc, inst); + return 1 | STEP_OVER; + + default: + util::stream_format(stream, "%-8s", ".WORD"); + format_addr(stream, inst); + return 1; + } +} diff --git a/src/devices/cpu/pace/pacedasm.h b/src/devices/cpu/pace/pacedasm.h new file mode 100644 index 00000000000..19471e0950a --- /dev/null +++ b/src/devices/cpu/pace/pacedasm.h @@ -0,0 +1,36 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + National Semiconductor PACE (IPC-16, INS8900) disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_PACE_PACEDASM_H +#define MAME_CPU_PACE_PACEDASM_H + +#pragma once + +class pace_disassembler : public util::disasm_interface +{ +public: + // construction/destruction + pace_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: + // internal helpers + void format_addr(std::ostream &stream, u16 addr); + void format_disp(std::ostream &stream, u8 disp); + void format_ea(std::ostream &stream, u16 pc, u16 inst); + + // tables + static const char *const s_cc[16]; + static const char *const s_flags[16]; +}; + +#endif // MAME_CPU_PACE_PACEDASM_H diff --git a/src/mame/drivers/ns5652.cpp b/src/mame/drivers/ns5652.cpp new file mode 100644 index 00000000000..54d8f3c434c --- /dev/null +++ b/src/mame/drivers/ns5652.cpp @@ -0,0 +1,59 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + unknown National Semiconductor INS8900 Multibus card (980305652) + +***************************************************************************/ + +#include "emu.h" +#include "cpu/pace/pace.h" +#include "machine/ins8250.h" + +class ns5652_state : public driver_device +{ +public: + ns5652_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + { + } + + void ns5652(machine_config &config); + +private: + void mem_map(address_map &map); + + required_device m_maincpu; +}; + + +void ns5652_state::mem_map(address_map &map) +{ + map(0x0000, 0x0bff).mirror(0xd000).rom().region("eproms", 0); + map(0xe800, 0xebff).ram(); // 4x MM2114J-3 +} + + +static INPUT_PORTS_START(ns5652) +INPUT_PORTS_END + +void ns5652_state::ns5652(machine_config &config) +{ + INS8900(config, m_maincpu, 1.8432_MHz_XTAL); // no other XTAL visible + m_maincpu->set_addrmap(AS_PROGRAM, &ns5652_state::mem_map); + + INS8250(config, "ace", 1.8432_MHz_XTAL); +} + +ROM_START(ns5652) + ROM_REGION16_LE(0x1800, "eproms", 0) // all MM2708Q + ROM_LOAD16_BYTE("5652_001b.bin", 0x0000, 0x0400, CRC(03acf738) SHA1(e512ccf64473e0b7291d8cc14f44858cac2048e6)) + ROM_LOAD16_BYTE("5652_004b.bin", 0x0001, 0x0400, CRC(b238b1ba) SHA1(90735194cc7f111fc7c1cdde1a9aab4945b00a7e)) + ROM_LOAD16_BYTE("5652_002b.bin", 0x0800, 0x0400, CRC(2fd33c25) SHA1(5f1bab6c149c19b8c57f9f014d7aecd5d287fae0)) + ROM_LOAD16_BYTE("5652_005b.bin", 0x0801, 0x0400, CRC(e1d559ed) SHA1(3093d28b661275c00de8145f8424f584a4854072)) + ROM_LOAD16_BYTE("5652_003b.bin", 0x1000, 0x0400, CRC(24abf1f8) SHA1(ef22ca58e59d8301aab9175ef7ac9dc97feae9ec)) + ROM_LOAD16_BYTE("5652_006b.bin", 0x1001, 0x0400, CRC(db1dca74) SHA1(05149e85237a742850446c01249c83ba373e66b3)) +ROM_END + +COMP(19??, ns5652, 0, 0, ns5652, ns5652, ns5652_state, empty_init, "National Semiconductor", "unknown INS8900 Multibus card (980305652)", MACHINE_IS_SKELETON) diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 0f0497f5ed4..19529ee9a4a 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -31511,6 +31511,9 @@ sfortea2 // sforteb // sfortec // +@source:ns5652.cpp +ns5652 // + @source:nsg6809.cpp pitchhit // diff --git a/src/mame/mess.flt b/src/mame/mess.flt index d7712b3b21d..7a84d298ce3 100644 --- a/src/mame/mess.flt +++ b/src/mame/mess.flt @@ -588,6 +588,7 @@ novag_diablo.cpp novag_presto.cpp novag_savant.cpp novag_sexpert.cpp +ns5652.cpp o2.cpp ob68k1a.cpp octane.cpp diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp index 7f820be5cfc..fd8e932658c 100644 --- a/src/tools/unidasm.cpp +++ b/src/tools/unidasm.cpp @@ -108,6 +108,7 @@ using util::BIT; #include "cpu/nec/necdasm.h" #include "cpu/ns32000/ns32000dasm.h" #include "cpu/nuon/nuondasm.h" +#include "cpu/pace/pacedasm.h" #include "cpu/patinhofeio/patinho_feio_dasm.h" #include "cpu/pdp1/pdp1dasm.h" #include "cpu/pdp1/tx0dasm.h" @@ -446,6 +447,7 @@ static const dasm_table_entry dasm_table[] = { "ns32000", le, 0, []() -> util::disasm_interface * { return new ns32000_disassembler; } }, { "nuon", be, 0, []() -> util::disasm_interface * { return new nuon_disassembler; } }, { "nsc8105", be, 0, []() -> util::disasm_interface * { return new m680x_disassembler(8105); } }, + { "pace", le, -1, []() -> util::disasm_interface * { return new pace_disassembler; } }, { "patinho_feio", le, 0, []() -> util::disasm_interface * { return new patinho_feio_disassembler; } }, { "pdp1", be, 0, []() -> util::disasm_interface * { return new pdp1_disassembler; } }, { "pdp8", be, 0, []() -> util::disasm_interface * { return new pdp8_disassembler; } }, -- cgit v1.2.3