From b6b1d91b0b959833e58326f67487006a3cbd5ed5 Mon Sep 17 00:00:00 2001 From: Patrick Mackinlay Date: Fri, 10 Jan 2025 12:32:02 +0700 Subject: sgi/gm1: add skeleton card [J.J. van der Heijden] --- src/mame/sgi/gm1.cpp | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/mame/sgi/gm1.h | 51 +++++++++++++++++++ src/mame/sgi/tt.cpp | 40 +++++++++++++-- 3 files changed, 224 insertions(+), 5 deletions(-) create mode 100644 src/mame/sgi/gm1.cpp create mode 100644 src/mame/sgi/gm1.h diff --git a/src/mame/sgi/gm1.cpp b/src/mame/sgi/gm1.cpp new file mode 100644 index 00000000000..f56a0006523 --- /dev/null +++ b/src/mame/sgi/gm1.cpp @@ -0,0 +1,138 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +/* + * Silicon Graphics GT Graphics (aka Clover 2) Graphics Manager 1 (GM1) board, part 030-0076-00[34]. + * + * TODO: + * - everything (skeleton only) + * + * WIP: + * - launch with -vme:slot9 gm1 [-vme:slot9:gm1:serial0 terminal] + * - skeleton is sufficient to pass gm1 diagnostics, but nothing else + */ + +#include "emu.h" +#include "gm1.h" + +//#define VERBOSE (LOG_GENERAL) + +#include "logmacro.h" + +DEFINE_DEVICE_TYPE(SGI_GM1, sgi_gm1_device, "sgi_gm1", "SGI GM1") + +sgi_gm1_device::sgi_gm1_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : device_t(mconfig, SGI_GM1, tag, owner, clock) + , device_vme_card_interface(mconfig, *this) + , m_cpu(*this, "cpu") + , m_duart(*this, "duart") + , m_serial(*this, "serial%u", 0U) +{ +} + +void sgi_gm1_device::cpu_map(address_map &map) +{ + map(0x0000'0000, 0x0000'ffff).rom().region("eprom", 0); + + map(0x0200'0000, 0x0200'000f).rw(m_duart, FUNC(scn2681_device::read), FUNC(scn2681_device::write)); + + map(0x9800'0000, 0x980f'ffff).ram().share("gm_dram"); // 1M? + + // polygon processor (pp) interface? + map(0xc800'2000, 0xc800'3fff).ram().share("pp_sram"); // 8K + map(0xc800'4000, 0xc800'4003).umask32(0xffff'0000).lr16([this]() { return m_pp_wc; }, "pp_wc_r"); + + map(0xcc00'0000, 0xcc00'0000).umask32(0xff00'0000).lrw8( + []() { return 0x02; }, "pp_sts_r", + [this](u8 data) { LOG("pp_cmd_w 0x%02x (%s)\n", data, machine().describe_context()); }, "pp_cmd_w"); + map(0xcc00'0010, 0xcc00'0013).umask32(0xffff'0000).lw16([this](u16 data) { m_pp_wc = data; }, "pp_wc_w"); + + map(0xce00'0000, 0xce00'ffff).ram().share("pp_ucode"); // 64K? +} + +void sgi_gm1_device::vme_a16_map(address_map &map) +{ + map(0x0, 0x3).umask32(0x0000'ffff).rw(FUNC(sgi_gm1_device::status_r), FUNC(sgi_gm1_device::reset_w)); + map(0x4, 0x7).umask32(0x0000'ffff).w(FUNC(sgi_gm1_device::interrupt_w)); + map(0x8, 0xb).umask32(0x0000'ffff).w(FUNC(sgi_gm1_device::interrupt_disable_w)); + map(0xc, 0xf).umask32(0x0000'ffff).w(FUNC(sgi_gm1_device::interrupt_vector_w)); +} +void sgi_gm1_device::vme_a32_map(address_map &map) +{ + map(0x0000'0000, 0x000f'ffff).ram().share("gm_dram"); + // TODO: pipe +} + +u16 sgi_gm1_device::status_r() { return 0x0700; } +void sgi_gm1_device::reset_w(u16 data) { LOG("reset_w 0x%04x (%s)\n", data, machine().describe_context()); } +void sgi_gm1_device::interrupt_w(u16 data) { LOG("interrupt_w 0x%04x (%s)\n", data, machine().describe_context()); } +void sgi_gm1_device::interrupt_disable_w(u16 data) { LOG("interrupt_disable_w 0x%04x (%s)\n", data, machine().describe_context()); } +void sgi_gm1_device::interrupt_vector_w(u16 data) { LOG("interrupt_vector_w 0x%04x (%s)\n", data, machine().describe_context()); } + +void sgi_gm1_device::device_add_mconfig(machine_config &config) +{ + /* + * irq source + * 1 unused + * 2 pp + * 3 unused + * 4 fifo + * 5 retrace + * 6 host + * 7 uart + */ + M68020(config, m_cpu, 16_MHz_XTAL); + m_cpu->set_addrmap(AS_PROGRAM, &sgi_gm1_device::cpu_map); + + SCN2681(config, m_duart, 3.6864_MHz_XTAL); // SCN2681AC1N24 + + RS232_PORT(config, m_serial[0], default_rs232_devices, nullptr); + RS232_PORT(config, m_serial[1], default_rs232_devices, nullptr); + + m_duart->irq_cb().set_inputline(m_cpu, INPUT_LINE_IRQ7); + 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 sgi_gm1_device::device_start() +{ + m_pp_wc = 0; +} + +void sgi_gm1_device::device_reset() +{ + /* + * #define GM_VME_BASE_ADDR 0xbd002000 // in VME A16 space + * #define GM_VME_DRAM_ADDR 0xb8800000 // in VME A32 space + * #define GM_VME_PIPE_ADDR 0xb8900000 // in VME A32 space + */ + vme_space(vme::AM_2d).install_device(0x2000, 0x200f, *this, &sgi_gm1_device::vme_a16_map); + vme_space(vme::AM_09).install_device(0x1880'0000, 0x189f'ffff, *this, &sgi_gm1_device::vme_a32_map); + + // FIXME: interrupts asserted at power-on? + m_cpu->set_input_line(INPUT_LINE_IRQ2, HOLD_LINE); + m_cpu->set_input_line(INPUT_LINE_IRQ5, HOLD_LINE); +} + +ROM_START(gm1) + ROM_REGION32_BE(0x10000, "eprom", 0) + + // "GM-1 Prom revision Thu Mar 16 18:52:42 PST 1989" + ROM_LOAD("070-0253-005.bin", 0x00000, 0x10000, CRC(a5b883b8) SHA1(ad22a07d0a57b012e708b38216b7f3e600e12597)) +ROM_END + +static INPUT_PORTS_START(gm1) +INPUT_PORTS_END + +tiny_rom_entry const *sgi_gm1_device::device_rom_region() const +{ + return ROM_NAME(gm1); +} + +ioport_constructor sgi_gm1_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(gm1); +} diff --git a/src/mame/sgi/gm1.h b/src/mame/sgi/gm1.h new file mode 100644 index 00000000000..2358d4b1a9f --- /dev/null +++ b/src/mame/sgi/gm1.h @@ -0,0 +1,51 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +#ifndef MAME_SGI_GM1_H +#define MAME_SGI_GM1_H + +#pragma once + +#include "cpu/m68000/m68020.h" + +#include "machine/mc68681.h" +#include "machine/timer.h" + +#include "bus/rs232/rs232.h" +#include "bus/vme/vme.h" + +class sgi_gm1_device + : public device_t + , public device_vme_card_interface +{ +public: + sgi_gm1_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); + +protected: + virtual tiny_rom_entry const *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; + + void cpu_map(address_map &map) ATTR_COLD; + void vme_a16_map(address_map &map) ATTR_COLD; + void vme_a32_map(address_map &map) ATTR_COLD; + + u16 status_r(); + void reset_w(u16 data); + void interrupt_w(u16 data); + void interrupt_disable_w(u16 data); + void interrupt_vector_w(u16 data); + +private: + required_device m_cpu; + required_device m_duart; + required_device_array m_serial; + + u16 m_pp_wc; // pp sram word count +}; + +DECLARE_DEVICE_TYPE(SGI_GM1, sgi_gm1_device) + +#endif // MAME_SGI_GM1_H diff --git a/src/mame/sgi/tt.cpp b/src/mame/sgi/tt.cpp index 0edc87acd3a..92ec810eb84 100644 --- a/src/mame/sgi/tt.cpp +++ b/src/mame/sgi/tt.cpp @@ -25,6 +25,9 @@ #include "ip4.h" +// graphics cards +#include "gm1.h" + //#define VERBOSE (0) #include "logmacro.h" @@ -69,6 +72,33 @@ static void vme_cards(device_slot_interface &device) device.option_add("enp10", VME_ENP10); } +static void slot8_cards(device_slot_interface &device) +{ + vme_cards(device); + + //device.option_add("ge4", SGI_GE4); // GT +} +static void slot9_cards(device_slot_interface &device) +{ + //device.option_add("de3", SGI_DE3); // B,G + device.option_add("gm1", SGI_GM1); // GT +} +static void slot10_cards(device_slot_interface &device) +{ + //device.option_add("gf3", SGI_GF3); // B,G + //device.option_add("rm1", SGI_RM1); // GT +} +static void slot11_cards(device_slot_interface &device) +{ + //device.option_add("tb2", SGI_TB2); // B,G + //device.option_add("rv1", SGI_RV1); // GT +} +static void slot12_cards(device_slot_interface &device) +{ + //device.option_add("zb2", SGI_ZB2); // G + //device.option_add("rm1", SGI_RM1); // GT +} + void ip4_state::tt12(machine_config &config, XTAL clock) { VME(config, m_vme); @@ -81,12 +111,12 @@ void ip4_state::tt12(machine_config &config, XTAL clock) VME_SLOT(config, m_slot[4], vme_cards, nullptr, false); VME_SLOT(config, m_slot[5], vme_cards, nullptr, false); VME_SLOT(config, m_slot[6], vme_cards, nullptr, false); - VME_SLOT(config, m_slot[7], vme_cards, nullptr, false); + VME_SLOT(config, m_slot[7], slot8_cards, nullptr, false); - VME_SLOT(config, m_slot[8], vme_cards, nullptr, false); - VME_SLOT(config, m_slot[9], vme_cards, nullptr, false); - VME_SLOT(config, m_slot[10], vme_cards, nullptr, false); - VME_SLOT(config, m_slot[11], vme_cards, nullptr, false); + VME_SLOT(config, m_slot[8], slot9_cards, nullptr, false); + VME_SLOT(config, m_slot[9], slot10_cards, nullptr, false); + VME_SLOT(config, m_slot[10], slot11_cards, nullptr, false); + VME_SLOT(config, m_slot[11], slot12_cards, nullptr, false); } void ip4_state::machine_start() -- cgit v1.2.3