From 5da18d74228cb91b07590867d22e2d704e54a986 Mon Sep 17 00:00:00 2001 From: AJR Date: Wed, 18 Dec 2019 11:07:59 -0500 Subject: New machines marked as NOT_WORKING ---------------------------------- VT52 [Dalby Datormuseum] --- scripts/src/cpu.lua | 17 +++++ scripts/target/mame/mess.lua | 2 + src/devices/cpu/vt50/vt50.cpp | 128 ++++++++++++++++++++++++++++++++++++++ src/devices/cpu/vt50/vt50.h | 87 ++++++++++++++++++++++++++ src/devices/cpu/vt50/vt50dasm.cpp | 115 ++++++++++++++++++++++++++++++++++ src/devices/cpu/vt50/vt50dasm.h | 54 ++++++++++++++++ src/mame/drivers/vt52.cpp | 100 +++++++++++++++++++++++++++++ src/mame/mame.lst | 3 + src/mame/mess.flt | 1 + src/tools/unidasm.cpp | 3 + 10 files changed, 510 insertions(+) create mode 100644 src/devices/cpu/vt50/vt50.cpp create mode 100644 src/devices/cpu/vt50/vt50.h create mode 100644 src/devices/cpu/vt50/vt50dasm.cpp create mode 100644 src/devices/cpu/vt50/vt50dasm.h create mode 100644 src/mame/drivers/vt52.cpp diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua index 4c5644c1bf7..f027f0aa329 100644 --- a/scripts/src/cpu.lua +++ b/scripts/src/cpu.lua @@ -2997,3 +2997,20 @@ if (CPUS["DSP56000"]~=null or _OPTIONS["with-tools"]) then table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/dsp56000/dsp56000d.cpp") table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/dsp56000/dsp56000d.h") end + +-------------------------------------------------- +-- DEC VT50/VT52 +--@src/devices/cpu/vt50/vt50.h,CPUS["VT50"] = true +-------------------------------------------------- + +if (CPUS["VT50"]~=null) then + files { + MAME_DIR .. "src/devices/cpu/vt50/vt50.cpp", + MAME_DIR .. "src/devices/cpu/vt50/vt50.h", + } +end + +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 diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 282e5de85d1..aeb5203c5c8 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -148,6 +148,7 @@ CPUS["F2MC16"] = true CPUS["CR16B"] = true CPUS["FR"] = true CPUS["DSP56000"] = true +CPUS["VT50"] = true -------------------------------------------------- -- specify available sound cores; some of these are @@ -2069,6 +2070,7 @@ files { MAME_DIR .. "src/mame/drivers/vax11.cpp", MAME_DIR .. "src/mame/drivers/rainbow.cpp", MAME_DIR .. "src/mame/drivers/vk100.cpp", + MAME_DIR .. "src/mame/drivers/vt52.cpp", MAME_DIR .. "src/mame/drivers/vt100.cpp", MAME_DIR .. "src/mame/drivers/vt220.cpp", MAME_DIR .. "src/mame/drivers/vt240.cpp", diff --git a/src/devices/cpu/vt50/vt50.cpp b/src/devices/cpu/vt50/vt50.cpp new file mode 100644 index 00000000000..260f2190aa2 --- /dev/null +++ b/src/devices/cpu/vt50/vt50.cpp @@ -0,0 +1,128 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + DEC VT50/VT52 CPU skeleton + +***************************************************************************/ + +#include "emu.h" +#include "vt50.h" +#include "vt50dasm.h" + +// device type definitions +DEFINE_DEVICE_TYPE(VT50_CPU, vt50_cpu_device, "vt50_cpu", "DEC VT50 CPU") +DEFINE_DEVICE_TYPE(VT52_CPU, vt52_cpu_device, "vt52_cpu", "DEC VT52 CPU") + +vt5x_cpu_device::vt5x_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int bbits, int ybits) + : cpu_device(mconfig, type, tag, owner, clock) + , m_rom_config("program", ENDIANNESS_LITTLE, 8, 10, 0) + , m_ram_config("data", ENDIANNESS_LITTLE, 8, 6 + ybits, 0) // actually 7 bits wide + , m_rom_cache(nullptr) + , m_ram_cache(nullptr) + , m_bbits(bbits) + , m_ybits(ybits) + , m_pc(0) + , m_rom_bank(0) + , m_mode_ff(false) + , m_done_ff(false) + , m_ac(0) + , m_buffer(0) + , m_x(0) + , m_y(0) + , m_x8(false) + , m_cursor_ff(false) + , m_video_process(false) +{ + m_rom_config.m_is_octal = true; + m_ram_config.m_is_octal = true; +} + +vt50_cpu_device::vt50_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : vt5x_cpu_device(mconfig, VT50_CPU, tag, owner, clock, 4, 4) +{ +} + +vt52_cpu_device::vt52_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : vt5x_cpu_device(mconfig, VT52_CPU, tag, owner, clock, 7, 5) +{ +} + +std::unique_ptr vt50_cpu_device::create_disassembler() +{ + return std::make_unique(); +} + +std::unique_ptr vt52_cpu_device::create_disassembler() +{ + return std::make_unique(); +} + +device_memory_interface::space_config_vector vt5x_cpu_device::memory_space_config() const +{ + return space_config_vector { + std::make_pair(AS_PROGRAM, &m_rom_config), + std::make_pair(AS_DATA, &m_ram_config) + }; +} + +void vt5x_cpu_device::device_start() +{ + m_rom_cache = space(AS_PROGRAM).cache<0, 0, ENDIANNESS_LITTLE>(); + m_ram_cache = space(AS_DATA).cache<0, 0, ENDIANNESS_LITTLE>(); + + set_icountptr(m_icount); + + state_add(VT5X_PC, "PC", m_pc).formatstr("%04O").mask(01777); + state_add(STATE_GENPC, "GENPC", m_pc).mask(01777).noshow(); + state_add(STATE_GENPCBASE, "CURPC", m_pc).mask(01777).noshow(); + state_add(STATE_GENFLAGS, "CURFLAGS", [this]() { + return (m_mode_ff ? 1 : 0) | (m_done_ff ? 2 : 0); + }).formatstr("%7s").noshow(); + state_add(VT5X_BANK, "BANK", m_rom_bank).mask(3); + state_add(VT5X_MODE, "MODE", m_mode_ff).noshow(); + state_add(VT5X_DONE, "DONE", m_done_ff).noshow(); + state_add(VT5X_AC, "AC", m_ac).formatstr("%03O").mask(0177); + state_add(VT5X_B, "B", m_buffer).formatstr(m_bbits > 6 ? "%03O" : "%02O").mask((1 << m_bbits) - 1); + state_add(VT5X_X, "X", m_x).formatstr("%03O").mask(0177); + state_add(VT5X_Y, "Y", m_y).formatstr("%02O").mask((1 << m_ybits) - 1); + state_add(VT5X_X8, "X8", m_x8); + state_add(VT5X_CFF, "CFF", m_cursor_ff); + state_add(VT5X_VID, "VID", m_video_process); + + save_item(NAME(m_pc)); + save_item(NAME(m_rom_bank)); + save_item(NAME(m_mode_ff)); + save_item(NAME(m_done_ff)); + save_item(NAME(m_ac)); + save_item(NAME(m_buffer)); + save_item(NAME(m_x)); + save_item(NAME(m_y)); + save_item(NAME(m_x8)); + save_item(NAME(m_cursor_ff)); + save_item(NAME(m_video_process)); +} + +void vt5x_cpu_device::device_reset() +{ + m_pc = 0; + m_rom_bank = 0; + m_video_process = false; +} + +void vt5x_cpu_device::execute_run() +{ + debugger_instruction_hook(m_pc); + + m_icount = 0; +} + +void vt5x_cpu_device::state_string_export(const device_state_entry &entry, std::string &str) const +{ + switch (entry.index()) + { + case STATE_GENFLAGS: + str = string_format("M%d %4s", m_mode_ff ? 1 : 0, m_done_ff ? "DONE" : ""); + break; + } +} diff --git a/src/devices/cpu/vt50/vt50.h b/src/devices/cpu/vt50/vt50.h new file mode 100644 index 00000000000..894a5bb7538 --- /dev/null +++ b/src/devices/cpu/vt50/vt50.h @@ -0,0 +1,87 @@ +// license:BSD-3-Clause +// copyright-holders:AJR + +#ifndef MAME_CPU_VT50_VT50_H +#define MAME_CPU_VT50_VT50_H + +#pragma once + +class vt5x_cpu_device : public cpu_device +{ +public: + enum { + VT5X_PC, VT5X_BANK, + VT5X_MODE, VT5X_DONE, + VT5X_AC, VT5X_B, VT5X_X, VT5X_Y, VT5X_X8, + VT5X_CFF, VT5X_VID + }; + +protected: + // construction/destruction + vt5x_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int bbits, int ybits); + + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // device_execute_interface overrides + virtual void execute_run() override; + + // device_memory_interface overrides + virtual space_config_vector memory_space_config() const override; + + // device_state_interface overrides + virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; + +private: + // address spaces + address_space_config m_rom_config; + address_space_config m_ram_config; + memory_access_cache<0, 0, ENDIANNESS_LITTLE> *m_rom_cache; + memory_access_cache<0, 0, ENDIANNESS_LITTLE> *m_ram_cache; + + // register dimensions + const u8 m_bbits; + const u8 m_ybits; + + // internal state + u16 m_pc; + u8 m_rom_bank; + bool m_mode_ff; + bool m_done_ff; + u8 m_ac; + u8 m_buffer; + u8 m_x; + u8 m_y; + bool m_x8; + bool m_cursor_ff; + bool m_video_process; + s32 m_icount; +}; + +class vt50_cpu_device : public vt5x_cpu_device +{ +public: + // device type constructor + vt50_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + +protected: + // device_disasm_interface overrides + virtual std::unique_ptr create_disassembler() override; +}; + +class vt52_cpu_device : public vt5x_cpu_device +{ +public: + // device type constructor + vt52_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + +protected: + // device_disasm_interface overrides + virtual std::unique_ptr create_disassembler() override; +}; + +DECLARE_DEVICE_TYPE(VT50_CPU, vt50_cpu_device) +DECLARE_DEVICE_TYPE(VT52_CPU, vt52_cpu_device) + +#endif // MAME_CPU_VT50_VT50_H diff --git a/src/devices/cpu/vt50/vt50dasm.cpp b/src/devices/cpu/vt50/vt50dasm.cpp new file mode 100644 index 00000000000..9b2e603e0c4 --- /dev/null +++ b/src/devices/cpu/vt50/vt50dasm.cpp @@ -0,0 +1,115 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + DEC VT50/VT52 microcode disassembler + +***************************************************************************/ + +#include "emu.h" +#include "vt50dasm.h" + +vt5x_disassembler::vt5x_disassembler(const char *const opcodes_e[8], const char *const opcodes_f[8], const char *const opcodes_g[8], const char *const jumps_h[2][8], const char *const opcodes_w[8]) + : util::disasm_interface() + , m_opcodes_e(opcodes_e) + , m_opcodes_f(opcodes_f) + , m_opcodes_g(opcodes_g) + , m_jumps_h(jumps_h) + , m_opcodes_w(opcodes_w) +{ +} + +vt50_disassembler::vt50_disassembler() + : vt5x_disassembler(s_opcodes_e, s_opcodes_f, s_opcodes_g, s_jumps_h, s_opcodes_w) +{ +} + +vt52_disassembler::vt52_disassembler() + : vt5x_disassembler(s_opcodes_e, s_opcodes_f, s_opcodes_g, s_jumps_h, s_opcodes_w) +{ +} + +const char *const vt5x_disassembler::s_opcodes_e[8] = { + "ZXZY", "X8", "IXDY", "IX", "ZA", "M1", "ZX", "M0" +}; + +const char *const vt5x_disassembler::s_opcodes_f[8] = { + "DXDY", "IA", "IA1", "IY", "DY", "IROM", "DX", "DA" +}; + +const char *const vt50_disassembler::s_opcodes_g[8] = { + "M2A", "A2M", "M2U", "B2M", "L40M", "U2M", "M2B", "SPARE" +}; + +const char *const vt52_disassembler::s_opcodes_g[8] = { + "M2A", "A2M", "M2U", "B2M", "M2X", "U2M", "M2B", "SPARE" +}; + +const char *const vt5x_disassembler::s_jumps_h[2][8] = { + { "PSC", "TAB", "KCL", "FRQ", "PRQ", "TRU", "UT", "TOS" }, // mode 0 + { "UR", "AEM", "ALM", "ADX", "AEM2", nullptr, "VSC", "KEY" } // mode 1 +}; + +const char *const vt5x_disassembler::s_opcodes_w[8] = { + "SCFF", "SVID", "B2Y", "CBFF", "ZCAV", "LPB", "EPR", "HPR!ZY" +}; + +u32 vt5x_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t vt5x_disassembler::disassemble(std::ostream &stream, offs_t pc, const vt5x_disassembler::data_buffer &opcodes, const vt5x_disassembler::data_buffer ¶ms) +{ + u8 opcode = opcodes.r8(pc); + + if (BIT(opcode, 7)) + { + util::stream_format(stream, "LD %03o", opcode & 0177); // execution varies by mode + return 1; + } + else if ((opcode & 0017) == 0) + { + stream << m_opcodes_w[(opcode & 0160) >> 4]; + return 1; + } + else + { + bool first = true; + if (BIT(opcode, 3)) + { + first = false; + stream << m_opcodes_e[(opcode & 0160) >> 4]; + } + if (BIT(opcode, 2)) + { + if (!first) + stream << "!"; + first = false; + stream << m_opcodes_f[(opcode & 0160) >> 4]; + } + if (BIT(opcode, 1)) + { + if (!first) + stream << "!"; + first = false; + stream << m_opcodes_g[(opcode & 0160) >> 4]; + } + if (BIT(opcode, 0)) + { + if (!first) + stream << "!"; + util::stream_format(stream, "%sJ", m_jumps_h[0][(opcode & 0160) >> 4]); + if (m_jumps_h[1][(opcode & 0160) >> 4] != nullptr) + util::stream_format(stream, "/%sJ", m_jumps_h[1][(opcode & 0160) >> 4]); + + u16 nextpc = pc + 2; + if ((opcode & 0164) == 0124) // IROM!TRUJ adjustment + nextpc += 0400; + util::stream_format(stream, " %04o", (nextpc & 01400) | opcodes.r8(pc + 1)); + return 2; + } + else + return 1; + } +} diff --git a/src/devices/cpu/vt50/vt50dasm.h b/src/devices/cpu/vt50/vt50dasm.h new file mode 100644 index 00000000000..ce9b16a3d06 --- /dev/null +++ b/src/devices/cpu/vt50/vt50dasm.h @@ -0,0 +1,54 @@ +// license:BSD-3-Clause +// copyright-holders:AJR + +#ifndef MAME_CPU_VT50_VT50DASM_H +#define MAME_CPU_VT50_VT50DASM_H + +#pragma once + +class vt5x_disassembler : public util::disasm_interface +{ +protected: + vt5x_disassembler(const char *const opcodes_e[8], const char *const opcodes_f[8], const char *const opcodes_g[8], const char *const jumps_h[2][8], const char *const opcodes_w[8]); + + // 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; + + // tables + static const char *const s_opcodes_e[8]; + static const char *const s_opcodes_f[8]; + static const char *const s_jumps_h[2][8]; + static const char *const s_opcodes_w[8]; + +private: + const char *const *m_opcodes_e; + const char *const *m_opcodes_f; + const char *const *m_opcodes_g; + const char *const (*m_jumps_h)[8]; + const char *const *m_opcodes_w; +}; + +class vt50_disassembler : public vt5x_disassembler +{ +public: + // construction/destruction + vt50_disassembler(); + +private: + // tables + static const char *const s_opcodes_g[8]; +}; + +class vt52_disassembler : public vt5x_disassembler +{ +public: + // construction/destruction + vt52_disassembler(); + +private: + // tables + static const char *const s_opcodes_g[8]; +}; + +#endif // MAME_CPU_VT50_VT50DASM_H diff --git a/src/mame/drivers/vt52.cpp b/src/mame/drivers/vt52.cpp new file mode 100644 index 00000000000..06a827a5690 --- /dev/null +++ b/src/mame/drivers/vt52.cpp @@ -0,0 +1,100 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/**************************************************************************** + + Skeleton driver for DEC VT50 terminal family. + + The VT50 "DECscope" was DEC's first video terminal to contain a CPU of + sorts, with TTL logic spanning two boards executing custom microcode. + It displayed 12 lines of 80-column text, using a standard character + generator that only contained uppercase letters and symbols. + + The VT52 used the same case and most of the same circuitry as the VT50, + but quickly displaced it by supporting 24 lines of text and a full ASCII + character generator (on a board of its own). VT50 and VT52 each had + minor variants differing in keyboard function and printer availability. + + The VT55 was a graphical terminal ostensibly in the same family as the + VT50 and VT52. Its hardware commonalities and differences are unknown. + +****************************************************************************/ + +#include "emu.h" +//#include "bus/rs232/rs232.h" +#include "cpu/vt50/vt50.h" +#include "machine/ay31015.h" +#include "screen.h" + +class vt52_state : public driver_device +{ +public: + vt52_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_uart(*this, "uart") + { + } + + void vt52(machine_config &mconfig); + +protected: + virtual void machine_start() override; + +private: + u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + + void rom_1k(address_map &map); + void ram_2k(address_map &map); + + required_device m_maincpu; + required_device m_uart; +}; + +void vt52_state::machine_start() +{ + m_uart->write_swe(0); +} + +u32 vt52_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + return 0; +} + +void vt52_state::rom_1k(address_map &map) +{ + map(00000, 01777).rom().region("program", 0); +} + +void vt52_state::ram_2k(address_map &map) +{ + map(00000, 03777).ram(); +} + +static INPUT_PORTS_START(vt52) +INPUT_PORTS_END + +void vt52_state::vt52(machine_config &mconfig) +{ + VT52_CPU(mconfig, m_maincpu, 13.824_MHz_XTAL); + m_maincpu->set_addrmap(AS_PROGRAM, &vt52_state::rom_1k); + m_maincpu->set_addrmap(AS_DATA, &vt52_state::ram_2k); + + AY51013(mconfig, m_uart); // TR1402 or equivalent + + screen_device &screen(SCREEN(mconfig, "screen", SCREEN_TYPE_RASTER)); + screen.set_raw(13.824_MHz_XTAL, 900, 0, 720, 256, 0, 192); + screen.set_screen_update(FUNC(vt52_state::screen_update)); +} + +ROM_START(vt52) + ROM_REGION(0x400, "program", 0) // bipolar PROMs + ROM_LOAD_NIB_LOW( "23-124a9.e29", 0x000, 0x200, CRC(3f5f3b92) SHA1(244c3100f277da3fce5513a92529a2c3e26a80b4)) + ROM_LOAD_NIB_HIGH("23-125a9.e26", 0x000, 0x200, CRC(b2a670c9) SHA1(fa8dd031dcafe4facff41e79603bdb388a6df928)) + ROM_LOAD_NIB_LOW( "23-126a9.e37", 0x200, 0x200, CRC(4883a600) SHA1(c5d9b0c21493065c75b4a7d52d5bd47f9851dfe7)) + ROM_LOAD_NIB_HIGH("23-127a9.e21", 0x200, 0x200, CRC(56c1c0d6) SHA1(ab0eb6e7bbafcc3d28481b62de3d3490f01c0174)) + + ROM_REGION(0x400, "chargen", 0) // 2608 character generator + ROM_LOAD("23-002b4.e1", 0x000, 0x400, NO_DUMP) +ROM_END + +COMP(1975, vt52, 0, 0, vt52, vt52, vt52_state, empty_init, "DEC", "VT52", MACHINE_IS_SKELETON) diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 232ddaf5393..6073e10a980 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -39880,6 +39880,9 @@ vstennisb // (c) 1984 Nintendo Co., Ltd. / Nintendo of Ame vstetris // (c) 1988 Atari wrecking // (c) 1984 Nintendo +@source:vt52.cpp +vt52 // 1975 Digital Equipment Corporation + @source:vt100.cpp vt100 // 1978 Digital Equipment Corporation vt100ac // 1979 Digital Equipment Corporation diff --git a/src/mame/mess.flt b/src/mame/mess.flt index 67500aa6b79..2326c6c9b14 100644 --- a/src/mame/mess.flt +++ b/src/mame/mess.flt @@ -944,6 +944,7 @@ vp60.cpp vsmile.cpp vsmileb.cpp vsmilepro.cpp +vt52.cpp vt100.cpp vt220.cpp vt240.cpp diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp index c7b125dc54f..7f820be5cfc 100644 --- a/src/tools/unidasm.cpp +++ b/src/tools/unidasm.cpp @@ -158,6 +158,7 @@ using util::BIT; #include "cpu/upd7810/upd7810_dasm.h" #include "cpu/v60/v60d.h" #include "cpu/v810/v810dasm.h" +#include "cpu/vt50/vt50dasm.h" #include "cpu/z180/z180dasm.h" #include "cpu/z8/z8dasm.h" #include "cpu/z80/z80dasm.h" @@ -523,6 +524,8 @@ static const dasm_table_entry dasm_table[] = { "upi41", le, 0, []() -> util::disasm_interface * { return new mcs48_disassembler(true, false); } }, { "v60", le, 0, []() -> util::disasm_interface * { return new v60_disassembler; } }, { "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; } }, { "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); } }, -- cgit v1.2.3