From 96ec01a614c4eda2864a27a98ecda4d6c229ebfb Mon Sep 17 00:00:00 2001 From: AJR Date: Mon, 13 Jan 2020 21:18:27 -0500 Subject: Add tentative VT61/VT62 disassembler and skeleton CPU device --- scripts/src/cpu.lua | 17 +++ scripts/target/mame/mess.lua | 1 + src/devices/cpu/vt61/vt61.cpp | 107 +++++++++++++++ src/devices/cpu/vt61/vt61.h | 69 ++++++++++ src/devices/cpu/vt61/vt61dasm.cpp | 275 ++++++++++++++++++++++++++++++++++++++ src/devices/cpu/vt61/vt61dasm.h | 34 +++++ src/mame/drivers/vt62.cpp | 33 +++-- src/tools/unidasm.cpp | 2 + 8 files changed, 521 insertions(+), 17 deletions(-) create mode 100644 src/devices/cpu/vt61/vt61.cpp create mode 100644 src/devices/cpu/vt61/vt61.h create mode 100644 src/devices/cpu/vt61/vt61dasm.cpp create mode 100644 src/devices/cpu/vt61/vt61dasm.h diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua index cb27ee3950c..b030e4958bd 100644 --- a/scripts/src/cpu.lua +++ b/scripts/src/cpu.lua @@ -3015,6 +3015,23 @@ if (CPUS["VT50"]~=null or _OPTIONS["with-tools"]) then table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/vt50/vt50dasm.h") end +-------------------------------------------------- +-- DEC VT61 +--@src/devices/cpu/vt61/vt61.h,CPUS["VT61"] = true +-------------------------------------------------- + +if (CPUS["VT61"]~=null) then + files { + MAME_DIR .. "src/devices/cpu/vt61/vt61.cpp", + MAME_DIR .. "src/devices/cpu/vt61/vt61.h", + } +end + +if (CPUS["VT61"]~=null or _OPTIONS["with-tools"]) then + table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/vt61/vt61dasm.cpp") + table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/vt61/vt61dasm.h") +end + -------------------------------------------------- -- National Semiconductor PACE/INS8900 --@src/devices/cpu/pace/pace.h,CPUS["PACE"] = true diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 3f04f87a7d8..e3d44505abc 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["VT61"] = true CPUS["PACE"] = true CPUS["WE32000"] = true CPUS["RX01"] = true diff --git a/src/devices/cpu/vt61/vt61.cpp b/src/devices/cpu/vt61/vt61.cpp new file mode 100644 index 00000000000..4d4971370c5 --- /dev/null +++ b/src/devices/cpu/vt61/vt61.cpp @@ -0,0 +1,107 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + DEC VT61 CPU + + Currently this device is just a stub with no actual execution core. + +***************************************************************************/ + +#include "emu.h" +#include "vt61.h" +#include "vt61dasm.h" + +// device type definition +DEFINE_DEVICE_TYPE(VT61_CPU, vt61_cpu_device, "vt61_cpu", "DEC VT61 CPU") + +vt61_cpu_device::vt61_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : cpu_device(mconfig, VT61_CPU, tag, owner, clock) + , m_program_config("microprogram", ENDIANNESS_LITTLE, 16, 10, -1) + , m_memory_config("memory", ENDIANNESS_LITTLE, 8, 16, 0) + , m_idr_config("IDR", ENDIANNESS_LITTLE, 8, 6, 0) + , m_program_cache(nullptr) + , m_memory_cache(nullptr) + , m_idr_cache(nullptr) + , m_pc(0) + , m_ac(0) + , m_mar(0) + , m_mdr(0) + , m_ir(0) + , m_sp{0} + , m_icount(0) +{ + m_program_config.m_is_octal = true; + m_memory_config.m_is_octal = true; + m_idr_config.m_is_octal = true; +} + +std::unique_ptr vt61_cpu_device::create_disassembler() +{ + return std::make_unique(); +} + +device_memory_interface::space_config_vector vt61_cpu_device::memory_space_config() const +{ + return space_config_vector { + std::make_pair(AS_PROGRAM, &m_program_config), + std::make_pair(AS_DATA, &m_memory_config), + std::make_pair(AS_IDR, &m_idr_config) + }; +} + +void vt61_cpu_device::device_start() +{ + m_program_cache = space(AS_PROGRAM).cache<1, -1, ENDIANNESS_LITTLE>(); + m_memory_cache = space(AS_DATA).cache<0, 0, ENDIANNESS_LITTLE>(); + m_idr_cache = space(AS_IDR).cache<0, 0, ENDIANNESS_LITTLE>(); + + set_icountptr(m_icount); + + state_add(VT61_PC, "PC", m_pc).mask(01777).formatstr("%5s"); + state_add(STATE_GENPC, "GENPC", m_pc).mask(01777).noshow(); + state_add(STATE_GENPCBASE, "CURPC", m_pc).mask(01777).noshow(); + state_add(VT61_AC, "AC", m_ac).formatstr("%03O"); + state_add(VT61_MAR, "MAR", m_mar).formatstr("%06O"); + state_add(VT61_MALO, "MALO", + [this]() { return m_mar & 000377; }, + [this](u8 data) { m_mar = (m_mar & 0177400) | data; } + ).noshow(); + state_add(VT61_MAHI, "MAHI", + [this]() { return (m_mar & 0177400) >> 8; }, + [this](u8 data) { m_mar = (m_mar & 000377) | (data << 8); } + ).noshow(); + state_add(VT61_MDR, "MDR", m_mdr).formatstr("%03O"); + state_add(VT61_IR, "IR", m_ir).mask(6); + for (int i = 0; i < 16; i++) + state_add(VT61_R0 + i, string_format("R%d", i).c_str(), m_sp[i]).formatstr("%03O"); + + save_item(NAME(m_pc)); + save_item(NAME(m_ac)); + save_item(NAME(m_mar)); + save_item(NAME(m_mdr)); + save_item(NAME(m_ir)); + save_item(NAME(m_sp)); +} + +void vt61_cpu_device::device_reset() +{ + m_pc = 0; +} + +void vt61_cpu_device::execute_run() +{ + debugger_instruction_hook(m_pc); + + m_icount = 0; +} + +void vt61_cpu_device::state_string_export(const device_state_entry &entry, std::string &str) const +{ + switch (entry.index()) + { + case VT61_PC: + str = string_format("%o:%03o", m_pc >> 8, m_pc & 0377); + break; + } +} diff --git a/src/devices/cpu/vt61/vt61.h b/src/devices/cpu/vt61/vt61.h new file mode 100644 index 00000000000..f2d463f273c --- /dev/null +++ b/src/devices/cpu/vt61/vt61.h @@ -0,0 +1,69 @@ +// license:BSD-3-Clause +// copyright-holders:AJR + +#ifndef MAME_CPU_VT61_VT61_H +#define MAME_CPU_VT61_VT61_H + +#pragma once + +class vt61_cpu_device : public cpu_device +{ +public: + enum { + VT61_PC, + VT61_AC, + VT61_MAR, VT61_MALO, VT61_MAHI, + VT61_MDR, + VT61_IR, + VT61_R0, VT61_R1, VT61_R2, VT61_R3, + VT61_R4, VT61_R5, VT61_R6, VT61_R7, + VT61_R8, VT61_R9, VT61_R10, VT61_R11, + VT61_R12, VT61_R13, VT61_R14, VT61_R15 + }; + + enum { + AS_IDR = 2 + }; + + // construction/destruction + vt61_cpu_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; + + // 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 spaces + address_space_config m_program_config; + address_space_config m_memory_config; + address_space_config m_idr_config; + memory_access_cache<1, -1, ENDIANNESS_LITTLE> *m_program_cache; + memory_access_cache<0, 0, ENDIANNESS_LITTLE> *m_memory_cache; + memory_access_cache<0, 0, ENDIANNESS_LITTLE> *m_idr_cache; + + // internal state + u16 m_pc; + u8 m_ac; + u16 m_mar; + u8 m_mdr; + u8 m_ir; + u8 m_sp[16]; // scratchpad memory + s32 m_icount; +}; + +DECLARE_DEVICE_TYPE(VT61_CPU, vt61_cpu_device) + +#endif // MAME_CPU_VT61_VT61_H diff --git a/src/devices/cpu/vt61/vt61dasm.cpp b/src/devices/cpu/vt61/vt61dasm.cpp new file mode 100644 index 00000000000..1471cf0a918 --- /dev/null +++ b/src/devices/cpu/vt61/vt61dasm.cpp @@ -0,0 +1,275 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + DEC VT61 microcode disassembler + + No microprogram source listing appears to have been published by DEC, + nor any instruction reference other than the decode signal references + in the schematics. The instruction format should not be regarded as + official, though it draws on some of DEC's PDP assembly languages. + +***************************************************************************/ + +#include "emu.h" +#include "vt61dasm.h" + +vt61_disassembler::vt61_disassembler() + : util::disasm_interface() +{ +} + +const char *const vt61_disassembler::s_opr_a[8] = { + "NOP", // NO OP A + "IAC", // INC AC + "LIR", // LD IR + "IMA", // INC MA + "SMD", // SHIFT MDR + "JMP0", // CLR PC + "CMPC8", // COMP PC 8 + "LDR" // LD RAM +}; + +const char *const vt61_disassembler::s_opr_b[16] = { + "OPR", // NO OP B + "SPARE", + "RC", // RESET C FLAG + "SPARE", + "SPARE", + "LMISC", // LD MISC FLAG + "LLED", // LD LED FLAG + "LMOD", // LD MODEM FLAG + "SKCLK", // SET KEYCLICK + "LINTRC", // LD INTRPT CONTROL + "SPARE", + "CNBR", // CLR NBR + "LSYNC", // LD SYNC + CLR NBX + "PLD", // PLD + "CVSR", // CLR VID SERV REQ + "ENVID" // ENABLE VID LOAD +}; + +const char *const vt61_disassembler::s_sources[12] = { + "AC", // SEL AC + "STAT1", // SEL STATUS 1 + "SW", // SEL SWITCHES + "CAS1", // SEL CAS 1 + "CAS2", // SEL CAS 2 + "RAM", // SEL RAM + "IDR", // SEL IDR + "UART", // SEL UART + "SPARE", + "TBSW", // TEST BOX SWITCH + "invalid", // SEL SPM LO + "invalid" // SEL SPM HI +}; + +const char *const vt61_disassembler::s_conditions[32][2] = { + { "NINTR1", "INTR1" }, // INTR 1 L + { "NBXF", "NBXT" }, // NBX L + { "NBRF", "NBRT" }, // NBR L + { "NF1", "F1" }, // F1 L + { "NF2", "F2" }, // F2 L + { "NCF", "CF" }, // C L + { "NURF", "URF" }, // UART R FLAG L + { "NUTB", "UTB" }, // UART T BUFF L + { "NXOFF", "XOFF" }, // DO X OFF L + { "NGOSR", "GOSR" }, // GOUT SER RQ L + { "NF3", "F3" }, // F3 L + { "NINTR2", "INTR2" }, // INTR 2 L + { "KEYUP", "KEYDN" }, // KEY DOWN L + { "NPWRUP", "PWRUP" }, // PWR UP L + { "NSYNC", "SYNC" }, // SYNC ENA L + { "PE", "NPE" }, // PARITY ERROR H + { "BZY", "NBZY" }, // MEM BZY H + { "EQ", "NE" }, // EQUAL H + { "CC", "CS" }, // CARRY OUT L + { "MDOFO", "MDOFZ" }, // MDR O.F. OUT H + { "NCSR", "CSR" }, // COPIER SER REQ L + { "NCPCF", "CPCF" }, // C-PCF L + { "T", "F" }, // TRUE H + { "NVSR", "VSR" }, // VID SERV REQ L + { "?H", "?L" }, + { "?H", "?L" }, + { "?H", "?L" }, + { "?H", "?L" }, + { "?H", "?L" }, + { "?H", "?L" }, + { "?H", "?L" }, + { "?H", "?L" } +}; + +u32 vt61_disassembler::opcode_alignment() const +{ + return 1; +} + +u32 vt61_disassembler::interface_flags() const +{ + return PAGED; +} + +u32 vt61_disassembler::page_address_bits() const +{ + return 8; +} + +void vt61_disassembler::dasm_spr(std::ostream &stream, u8 r) +{ + if (BIT(r, 4)) + util::stream_format(stream, "IR%d", r & 9); + else + util::stream_format(stream, "R%d", r); +} + +void vt61_disassembler::dasm_source(std::ostream &stream, u16 inst) +{ + if ((inst & 003000) == 003000) + util::stream_format(stream, "#%03o", inst & 000377); + else + { + if ((inst & 003400) == 002400 && (inst & 070000) != 070000) + dasm_spr(stream, (inst & 000170) >> 2 | (inst & 000200) >> 7); + else + stream << s_sources[(inst & 003600) >> 7]; + if ((inst & 000007) != 0 && (inst & 0170000) != 0100000) + stream << "," << s_opr_a[inst & 000007]; + } +} + +offs_t vt61_disassembler::disassemble(std::ostream &stream, offs_t pc, const vt61_disassembler::data_buffer &opcodes, const vt61_disassembler::data_buffer ¶ms) +{ + u16 inst = opcodes.r16(pc); + offs_t flags = SUPPORTED; + + if (!BIT(inst, 15)) + { + if ((inst & 074000) == 054000) + { + stream << "LDU"; + if ((inst & 000007) != 0 && (inst & 003000) != 003000) + { + stream << " " << s_opr_a[inst & 000007]; + if ((inst & 000007) == 5) + flags |= STEP_OUT; + } + } + else + { + switch (inst & 070000) + { + case 000000: + stream << "LAC "; + break; + + case 040000: + stream << "LMA " << (BIT(inst, 11) ? "HI," : "LO,"); + break; + + case 050000: + stream << "JMP "; + break; + + case 060000: + if (BIT(inst, 11)) + stream << "LMD "; + else + stream << "CAS3 "; + break; + + case 070000: + stream << "LSP "; + dasm_spr(stream, (inst & 000170) >> 2 | (inst & 004000) >> 11); + stream << ","; + break; + + default: + stream << "LD? "; + break; + } + + dasm_source(stream, inst); + if ((inst & 000007) == 5 && (inst & 003000) != 003000) + flags |= STEP_OUT; + } + } + else if (BIT(inst, 14)) + { + util::stream_format(stream, "BR %s,%03o", s_conditions[(inst & 017400) >> 8][BIT(inst, 13)], inst & 000377); + } + else if (BIT(inst, 13)) + { + if ((inst & 007407) == 0) + stream << "NOP"; + else + { + stream << s_opr_b[(inst & 007400) >> 8]; + if ((inst & 000007) != 0) + { + stream << " " << s_opr_a[inst & 000007]; + if ((inst & 000207) == 000204) + stream << "A"; // ENABLE MDR A (CAS DATA) + if ((inst & 000107) == 000104) + stream << "B"; // ENABLE MDR B (SYNC DATA IN) + if ((inst & 000007) == 5) + flags |= STEP_OUT; + } + } + } + else if (BIT(inst, 12)) + { + stream << "CMP "; + dasm_source(stream, inst); + if ((inst & 000007) == 5 && (inst & 003000) != 003000) + flags |= STEP_OUT; + } + else switch (inst & 000007) + { + case 0: + stream << "CMA"; + break; + + case 1: + stream << "ORA "; + dasm_source(stream, inst); + break; + + case 2: + stream << "XOR "; + dasm_source(stream, inst); + break; + + case 3: + stream << "AND "; + dasm_source(stream, inst); + break; + + case 4: + stream << "DCA"; + if (BIT(inst, 11)) + stream << " C"; + break; + + case 5: + stream << "ADD "; + if (BIT(inst, 11)) + stream << "C,"; + dasm_source(stream, inst); + break; + + case 6: + stream << "SUB "; + if (BIT(inst, 11)) + stream << "C,"; + dasm_source(stream, inst); + break; + + case 7: + stream << "SLA"; + if (BIT(inst, 11)) + stream << " C"; + break; + } + + return 1 | flags; +} diff --git a/src/devices/cpu/vt61/vt61dasm.h b/src/devices/cpu/vt61/vt61dasm.h new file mode 100644 index 00000000000..a2f038f1458 --- /dev/null +++ b/src/devices/cpu/vt61/vt61dasm.h @@ -0,0 +1,34 @@ +// license:BSD-3-Clause +// copyright-holders:AJR + +#ifndef MAME_CPU_VT61_VT61DASM_H +#define MAME_CPU_VT61_VT61DASM_H + +#pragma once + +class vt61_disassembler : public util::disasm_interface +{ +public: + // construction/destruction + vt61_disassembler(); + +protected: + // disassembler overrides + virtual u32 opcode_alignment() const override; + virtual u32 interface_flags() const override; + virtual u32 page_address_bits() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + // tables + static const char *const s_opr_a[8]; + static const char *const s_opr_b[16]; + static const char *const s_sources[12]; + static const char *const s_conditions[32][2]; + + // disassembly helpers + void dasm_spr(std::ostream &stream, u8 r); + void dasm_source(std::ostream &stream, u16 inst); +}; + +#endif // MAME_CPU_VT61_VT61DASM_H diff --git a/src/mame/drivers/vt62.cpp b/src/mame/drivers/vt62.cpp index 2a1bce2ee8e..ec37e99515d 100644 --- a/src/mame/drivers/vt62.cpp +++ b/src/mame/drivers/vt62.cpp @@ -8,7 +8,7 @@ #include "emu.h" //#include "bus/rs232/rs232.h" -//#include "cpu/vt61/vt61.h" +#include "cpu/vt61/vt61.h" #include "machine/ay31015.h" //#include "sound/spkrdev.h" #include "screen.h" @@ -19,6 +19,7 @@ class vt62_state : public driver_device public: vt62_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") , m_uart(*this, "uart") { } @@ -31,11 +32,11 @@ protected: private: u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - //void micro_map(address_map &map); - //void memory_map(address_map &map); - //void decode_map(address_map &map); + void micro_map(address_map &map); + void memory_map(address_map &map); + void decode_map(address_map &map); - //required_device m_maincpu; + required_device m_maincpu; required_device m_uart; //required_ioport_array<8> m_keys; //required_ioport m_baud_sw; @@ -50,35 +51,33 @@ u32 vt62_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const return 0; } -#ifdef UNUSED_DEFINITION void vt62_state::micro_map(address_map &map) { - map(0x000, 0x3ff).rom().region("crom", 0); + map(00000, 01777).rom().region("crom", 0); } void vt62_state::memory_map(address_map &map) { - map(0x0000, 0x00ff).mirror(0x4f00).ram(); // static RAM A - map(0x1000, 0x1fff).mirror(0x4000).ram(); // dynamic RAM B - map(0x2000, 0x2fff).mirror(0x4000).ram(); // dynamic RAM C - map(0x8000, 0x9fff).mirror(0x6000).rom().region("mrom", 0); + map(0000000, 0000377).mirror(0047400).ram(); // static RAM A + map(0010000, 0013777).mirror(0040000).ram(); // dynamic RAM B + map(0020000, 0023777).mirror(0040000).ram(); // dynamic RAM C + map(0100000, 0117777).mirror(0060000).rom().region("mrom", 0); } void vt62_state::decode_map(address_map &map) { - map(0x00, 0x3f).rom().region("idr", 0); + map(000, 077).rom().region("idr", 0); } -#endif static INPUT_PORTS_START(vt62) INPUT_PORTS_END void vt62_state::vt62(machine_config &mconfig) { - //VT61_CPU(mconfig, m_maincpu, 15.36_MHz_XTAL); - //m_maincpu->set_addrmap(AS_PROGRAM, &vt62_state::micro_map); - //m_maincpu->set_addrmap(AS_DATA, &vt62_state::memory_map); - //m_maincpu->set_addrmap(vt61_cpu_device::AS_IDR, &vt62_state::decode_map); + VT61_CPU(mconfig, m_maincpu, 15.36_MHz_XTAL); + m_maincpu->set_addrmap(AS_PROGRAM, &vt62_state::micro_map); + m_maincpu->set_addrmap(AS_DATA, &vt62_state::memory_map); + m_maincpu->set_addrmap(vt61_cpu_device::AS_IDR, &vt62_state::decode_map); AY51013(mconfig, m_uart); diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp index bf529d347c9..8dd89b682f8 100644 --- a/src/tools/unidasm.cpp +++ b/src/tools/unidasm.cpp @@ -161,6 +161,7 @@ using util::BIT; #include "cpu/v60/v60d.h" #include "cpu/v810/v810dasm.h" #include "cpu/vt50/vt50dasm.h" +#include "cpu/vt61/vt61dasm.h" #include "cpu/we32000/we32100d.h" #include "cpu/z180/z180dasm.h" #include "cpu/z8/z8dasm.h" @@ -531,6 +532,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; } }, + { "vt61", le, -1, []() -> util::disasm_interface * { return new vt61_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); } }, -- cgit v1.2.3