diff options
author | 2024-11-21 16:55:10 +0700 | |
---|---|---|
committer | 2024-11-21 16:55:31 +0700 | |
commit | 959ed9664e779f2c810b58c3ff67f06e4b8015de (patch) | |
tree | b969ec6bd70f9fb0ee660c63436d0bc7e34e4719 /src/devices/bus | |
parent | 25dc6e8aadee32ad0101b448b3878a672123b58c (diff) |
tp880v: added Tadpole Technology TP880V VME single-board computer [Plamen Mihaylov]
Diffstat (limited to 'src/devices/bus')
-rw-r--r-- | src/devices/bus/vme/tp880v.cpp | 168 | ||||
-rw-r--r-- | src/devices/bus/vme/tp880v.h | 57 | ||||
-rw-r--r-- | src/devices/bus/vme/vme_cards.cpp | 2 |
3 files changed, 227 insertions, 0 deletions
diff --git a/src/devices/bus/vme/tp880v.cpp b/src/devices/bus/vme/tp880v.cpp new file mode 100644 index 00000000000..a3a2e12b0f6 --- /dev/null +++ b/src/devices/bus/vme/tp880v.cpp @@ -0,0 +1,168 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +/* + * Tadpole Technology TP880V + * + * Sources: + * - TPROM/88K User Manual, Monitor/Debugger For 88000 Boards, Issue: 1.3, 26 June 1990, Part No. DS-1003 + * + * TODO: + * - cio hookup is incomplete, inter-processor interrupts are not working + * - dmac + * - vme + * - leds and switches + */ + +#include "emu.h" +#include "tp880v.h" + +#include "bus/nscsi/hd.h" +#include "bus/nscsi/tape.h" + +#define VERBOSE 0 +#include "logmacro.h" + +DEFINE_DEVICE_TYPE(VME_TP880V, vme_tp880v_card_device, "tp880v", "Tadpole Technology TP880V") + +vme_tp880v_card_device::vme_tp880v_card_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : device_t(mconfig, VME_TP880V, tag, owner, clock) + , device_vme_card_interface(mconfig, *this) + , m_cpu(*this, "cpu") + , m_mmu(*this, "mmu%u", 0U) + , m_ios(*this, "ios") + , m_cio(*this, "cio%u", 0U) + , m_dma(*this, "dma") + , m_rtc(*this, "rtc") + , m_scsi(*this, "scsi:7:ncr53c90") + , m_duart(*this, "duart") + , m_serial(*this, "serial%u", 0U) + , m_ram(*this, "ram") + , m_ram_68k(nullptr) +{ +} + +ROM_START(tp880v) + ROM_REGION16_BE(0x20000, "eprom", 0) + ROM_SYSTEM_BIOS(0, "v421", "TP880V Monitor - Revision R4.21") + ROMX_LOAD("880-v__v4.2.1.bin", 0x00000, 0x20000, CRC(c5e64026) SHA1(724f54573b1b0c79f20250fdb6434bb2248c5e04), ROM_GROUPWORD | ROM_REVERSE | ROM_BIOS(0)) // D27C1024D-15 +ROM_END + +static INPUT_PORTS_START(tp880v) +INPUT_PORTS_END + +const tiny_rom_entry *vme_tp880v_card_device::device_rom_region() const +{ + return ROM_NAME(tp880v); +} + +ioport_constructor vme_tp880v_card_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(tp880v); +} + +void vme_tp880v_card_device::device_start() +{ + m_ram_68k = util::big_endian_cast<u16>(m_ram.target()); +} + +void vme_tp880v_card_device::device_reset() +{ +} + +static void scsi_devices(device_slot_interface &device) +{ + device.option_add("harddisk", NSCSI_HARDDISK); + device.option_add("tape", NSCSI_TAPE); + device.option_add("ncr53c90", NCR53C90); +} + +void vme_tp880v_card_device::device_add_mconfig(machine_config &config) +{ + MC88100(config, m_cpu, 40_MHz_XTAL / 2); + m_cpu->set_addrmap(AS_PROGRAM, &vme_tp880v_card_device::cpu_mem); + m_cpu->set_cmmu_code([this](u32 const address) -> mc88200_device & { return *m_mmu[0]; }); + m_cpu->set_cmmu_data([this](u32 const address) -> mc88200_device & { return *m_mmu[1]; }); + + MC88200(config, m_mmu[0], 40_MHz_XTAL / 2, 0x7e).set_mbus(m_cpu, AS_PROGRAM); + MC88200(config, m_mmu[1], 40_MHz_XTAL / 2, 0x7f).set_mbus(m_cpu, AS_PROGRAM); + + M68000(config, m_ios, 10'000'000); + m_ios->set_addrmap(AS_PROGRAM, &vme_tp880v_card_device::ios_mem); + + Z8036(config, m_cio[0], 4'000'000); // Z0803606VSC + m_cio[0]->irq_wr_cb().set_inputline(m_ios, INPUT_LINE_IRQ4); // ? + Z8036(config, m_cio[1], 4'000'000); // Z0803606VSC + m_cio[0]->irq_wr_cb().set_inputline(m_ios, INPUT_LINE_IRQ1); // ? + + // TODO: MC68440 is function and pin compatible with MC68450/HD63450, but + // has only two DMA channels instead of four. + HD63450(config, m_dma, 10'000'000); // MC68440FN10 + m_dma->set_cpu_tag(m_ios); + m_dma->irq_callback().set_inputline(m_ios, INPUT_LINE_IRQ3); + m_dma->dma_read<0>().set(m_scsi, FUNC(ncr53c90_device::dma_r)); + m_dma->dma_write<0>().set(m_scsi, FUNC(ncr53c90_device::dma_w)); + + M48T02(config, m_rtc, 0); // MK40T02B-25 + + NSCSI_BUS(config, "scsi", 0); + NSCSI_CONNECTOR(config, "scsi:0", scsi_devices, "harddisk", false); + NSCSI_CONNECTOR(config, "scsi:1", scsi_devices, nullptr, false); + NSCSI_CONNECTOR(config, "scsi:2", scsi_devices, "tape", false); + NSCSI_CONNECTOR(config, "scsi:3", scsi_devices, nullptr, false); + NSCSI_CONNECTOR(config, "scsi:4", scsi_devices, nullptr, false); + NSCSI_CONNECTOR(config, "scsi:5", scsi_devices, nullptr, false); + NSCSI_CONNECTOR(config, "scsi:6", scsi_devices, nullptr, false); + NSCSI_CONNECTOR(config, "scsi:7").option_set("ncr53c90", NCR53C90).machine_config( + [this](device_t *device) + { + ncr53c90_device &ncr53c90(downcast<ncr53c90_device &>(*device)); + + ncr53c90.set_clock(10'000'000); + ncr53c90.irq_handler_cb().set_inputline(m_ios, INPUT_LINE_IRQ2); + ncr53c90.drq_handler_cb().set(m_dma, FUNC(hd63450_device::drq0_w)); + }); + + SCN2681(config, m_duart, 3.6864_MHz_XTAL); + m_duart->irq_cb().set_inputline(m_ios, INPUT_LINE_IRQ6); + m_duart->outport_cb().set([this](int state) { m_cpu->set_input_line(INPUT_LINE_RESET, state); }).bit(5); + + RS232_PORT(config, m_serial[0], default_rs232_devices, "terminal"); + RS232_PORT(config, m_serial[1], default_rs232_devices, nullptr); + + m_duart->a_tx_cb().set(m_serial[0], FUNC(rs232_port_device::write_txd)); + m_duart->b_tx_cb().set(m_serial[1], FUNC(rs232_port_device::write_txd)); + + m_serial[0]->rxd_handler().set(m_duart, FUNC(scn2681_device::rx_a_w)); + m_serial[1]->rxd_handler().set(m_duart, FUNC(scn2681_device::rx_b_w)); +} + +void vme_tp880v_card_device::cpu_mem(address_map &map) +{ + map(0x0000'0000, 0x003f'ffff).ram().share("ram"); + + map(0xfff0'0002, 0xfff0'0002).select(0x3f00).lrw8( + [this](offs_t offset) { return m_cio[0]->read(offset >> 8); }, "cio0_r", + [this](offs_t offset, u8 data) { m_cio[0]->write(offset >> 8, data); }, "cio0_w"); + map(0xfff0'8002, 0xfff0'8002).select(0x3f00).lrw8( + [this](offs_t offset) { return m_cio[1]->read(offset >> 8); }, "cio1_r", + [this](offs_t offset, u8 data) { m_cio[1]->write(offset >> 8, data); }, "cio1_w"); + + //map(0xfff1'0000, 0xfff1'0000); // vme iack vector? +} + +void vme_tp880v_card_device::ios_mem(address_map &map) +{ + map(0x00'0000, 0x01'ffff).rom().region("eprom", 0); + + map(0x10'0000, 0x10'3fff).ram(); // SRAM + + map(0x20'0000, 0x20'001f).rw(m_duart, FUNC(scn2681_device::read), FUNC(scn2681_device::write)).umask16(0x00ff); + map(0x24'0000, 0x2f'001f).m(m_scsi, FUNC(ncr53c90_device::map)).umask16(0x00ff); + map(0x28'0000, 0x28'00ff).rw(m_dma, FUNC(hd63450_device::read), FUNC(hd63450_device::write)); + map(0x2c'0000, 0x2c'0fff).rw(m_rtc, FUNC(m48t02_device::read), FUNC(m48t02_device::write)).umask16(0x00ff); + + map(0x80'0000, 0xbf'ffff).lrw16( + [this](offs_t offset, u16 mem_mask) { return m_ram_68k[offset]; }, "ram_68k_r", + [this](offs_t offset, u16 data, u16 mem_mask) { COMBINE_DATA(&m_ram_68k[offset]); }, "ram_68k_w"); +} diff --git a/src/devices/bus/vme/tp880v.h b/src/devices/bus/vme/tp880v.h new file mode 100644 index 00000000000..d2f60273550 --- /dev/null +++ b/src/devices/bus/vme/tp880v.h @@ -0,0 +1,57 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +#ifndef MAME_BUS_VME_TP880V_H +#define MAME_BUS_VME_TP880V_H + +#pragma once + +#include "cpu/m68000/m68000.h" +#include "cpu/m88000/m88000.h" +#include "machine/hd63450.h" +#include "machine/mc68681.h" +#include "machine/mc88200.h" +#include "machine/ncr53c90.h" +#include "machine/timekpr.h" +#include "machine/z8536.h" + +#include "bus/vme/vme.h" +#include "bus/rs232/rs232.h" + +class vme_tp880v_card_device + : public device_t + , public device_vme_card_interface +{ +public: + vme_tp880v_card_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); + +protected: + virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD; + virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; + virtual ioport_constructor device_input_ports() const override ATTR_COLD; + virtual void device_start() override ATTR_COLD; + virtual void device_reset() override ATTR_COLD; + +private: + void cpu_mem(address_map &map) ATTR_COLD; + void ios_mem(address_map &map) ATTR_COLD; + + required_device<mc88100_device> m_cpu; + required_device_array<mc88200_device, 2> m_mmu; + required_device<m68000_device> m_ios; + + required_device_array<z8036_device, 2> m_cio; + required_device<hd63450_device> m_dma; + required_device<m48t02_device> m_rtc; + required_device<ncr53c90_device> m_scsi; + required_device<scn2681_device> m_duart; + + required_device_array<rs232_port_device, 2> m_serial; + + required_shared_ptr<u32> m_ram; + util::endian_cast<u32, u16, util::endianness::big> m_ram_68k; +}; + +DECLARE_DEVICE_TYPE(VME_TP880V, vme_tp880v_card_device) + +#endif // MAME_BUS_VME_TP880V_H diff --git a/src/devices/bus/vme/vme_cards.cpp b/src/devices/bus/vme/vme_cards.cpp index cc6d26b2bae..d2d0245e7a0 100644 --- a/src/devices/bus/vme/vme_cards.cpp +++ b/src/devices/bus/vme/vme_cards.cpp @@ -24,6 +24,7 @@ #include "sys68k_cpu30.h" #include "sys68k_iscsi.h" #include "sys68k_isio.h" +#include "tp880v.h" #include "tp881v.h" void vme_cards(device_slot_interface &device) @@ -63,5 +64,6 @@ void vme_cards(device_slot_interface &device) device.option_add("sys68k_cpu33", VME_SYS68K_CPU33); device.option_add("sys68k_iscsi1", VME_SYS68K_ISCSI1), device.option_add("sys68k_isio1", VME_SYS68K_ISIO1), + device.option_add("tp880v", VME_TP880V); device.option_add("tp881v", VME_TP881V); } |