summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Patrick Mackinlay <pmackinlay@hotmail.com>2023-07-17 15:14:02 +0700
committer Patrick Mackinlay <pmackinlay@hotmail.com>2023-07-17 15:14:02 +0700
commit908d476f0c2757bffb18e6423f13e5f36aa141f9 (patch)
tree78510231bd67e569c29d0f46c7d0936812019273
parentadc3349c1ce6da3e6e2a483c822d7f5e375f53c9 (diff)
sgi/vc1: new device
-rw-r--r--src/mame/sgi/vc1.cpp206
-rw-r--r--src/mame/sgi/vc1.h32
2 files changed, 238 insertions, 0 deletions
diff --git a/src/mame/sgi/vc1.cpp b/src/mame/sgi/vc1.cpp
new file mode 100644
index 00000000000..1df072aabf8
--- /dev/null
+++ b/src/mame/sgi/vc1.cpp
@@ -0,0 +1,206 @@
+// license:BSD-3-Clause
+// copyright-holders:Patrick Mackinlay
+
+/*
+ * Silicon Graphics Video Controller (VC1).
+ *
+ * TODO:
+ * - everything; this stub is only enough to pass power-on diagnostics
+ */
+
+#include "emu.h"
+#include "vc1.h"
+
+//#define VERBOSE (LOG_GENERAL)
+
+#include "logmacro.h"
+
+DEFINE_DEVICE_TYPE(SGI_VC1, sgi_vc1_device, "sgi_vc1", "SGI VC1")
+
+sgi_vc1_device::sgi_vc1_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, SGI_VC1, tag, owner, clock)
+{
+}
+
+void sgi_vc1_device::device_start()
+{
+ m_ram = std::make_unique<u8[]>(0x8000); // TC55328J-35 32,768x8 CMOS STATIC RAM
+
+ save_item(NAME(m_addr));
+ save_item(NAME(m_reg));
+ save_item(NAME(m_xmap));
+
+ save_pointer(NAME(m_ram), 0x8000);
+}
+
+void sgi_vc1_device::device_reset()
+{
+ m_addr = 0;
+}
+
+enum vc1_cmd : unsigned
+{
+ REGISTER = 0, // video timing, cursor control, display id control, xmap control
+ XMAP_MODE = 1,
+ EXT_RAM = 2,
+ TEST = 3, // test registers
+ ADDR_LO = 4,
+ ADDR_HI = 5,
+ SYS_CTRL = 6,
+};
+
+u8 sgi_vc1_device::read(offs_t offset)
+{
+ switch (offset)
+ {
+ case REGISTER:
+ return m_reg[m_addr++];
+ case XMAP_MODE:
+ return m_xmap[m_addr++];
+ case EXT_RAM:
+ return m_ram[m_addr & 0x7fffU];
+ case TEST:
+ return 0; // vc1 revision?
+ case ADDR_LO:
+ return u8(m_addr);
+ case ADDR_HI:
+ return m_addr >> 8;
+ default:
+ LOG("read offset %d\n", offset);
+ return 0;
+ }
+}
+
+enum vc1_reg : unsigned
+{
+ // video timing generator
+ VID_EP = 0x00,
+ VID_LC = 0x02,
+ VID_SC = 0x04,
+ VID_TSA = 0x06,
+ VID_TSB = 0x07,
+ VID_TSC = 0x08,
+ VID_LP = 0x09,
+ VID_LS_EP = 0x0b,
+ VID_LR = 0x0d,
+ VID_FC = 0x10,
+ VID_ENABLE = 0x14,
+
+ // cursor generator
+ CUR_EP = 0x20,
+ CUR_XL = 0x22,
+ CUR_YL = 0x24,
+ CUR_MODE = 0x26,
+ CUR_BX = 0x27,
+ CUR_LY = 0x28,
+ CUR_YC = 0x2a,
+ CUR_XC = 0x2c,
+ CUR_CC = 0x2e,
+ CUR_RC = 0x30,
+
+ // display id generation
+ DID_EP = 0x40,
+ DID_END_EP = 0x42,
+ DID_HOR_DIV = 0x44,
+ DID_HOR_MOD = 0x45,
+ DID_LP = 0x46,
+ DID_LS_EP = 0x48,
+ DID_WC = 0x4a,
+ DID_RC = 0x4c,
+ DID_XL = 0x4e,
+ DID_XD5 = 0x50,
+ DID_XM5 = 0x51,
+ DID_DID = 0x52,
+
+ // control register
+ BLKOUT_EVEN = 0x60,
+ BLKOUT_ODD = 0x61,
+ AUXVIDEO_MAP = 0x62,
+};
+
+static const u8 reg_mask[] =
+{
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+
+ 0xff, 0xff, 0x07, 0xff, 0x0f, 0xff, 0xff, 0xff,
+ 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+};
+
+void sgi_vc1_device::write(offs_t offset, u8 data)
+{
+ switch (offset)
+ {
+ case REGISTER:
+ if (m_addr < std::size(reg_mask))
+ {
+ m_reg[m_addr] = data & reg_mask[m_addr];
+
+ if (VERBOSE & LOG_GENERAL)
+ {
+ static const char *const reg_name[] =
+ {
+ "VID_EP", "", "VID_LC", "", "VID_SC", "", "VID_TSA", "VID_TSB",
+ "VID_TSC", "VID_LP", nullptr, "VID_LS_EP", nullptr, "VID_LR", nullptr, nullptr,
+ "VID_FC", "", nullptr, nullptr, "VID_ENABLE", "", nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+
+ "CUR_EP", "", "CUR_XL", "", "CUR_YL", "", "CUR_MODE", "CUR_BX",
+ "CUR_LY", "", "CUR_YC", "", "CUR_XC", "", "CUR_CC", "",
+ "CUR_RC", "", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+
+ "DID_EP", "", "DID_END_EP", "", "DID_HOR_DIV", "DID_HOR_MOD", "DID_LP", "",
+ "DID_LS_EP", "", "DID_WC", "", "DID_RC", "", "DID_XL", "",
+ "DID_XD5", "DID_XM5", "DID_DID", "", nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+
+ "BLKOUT_EVEN", "BLKOUT_ODD", "AUXVIDEO_MAP", "", nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ };
+
+ if (!reg_name[m_addr])
+ LOG("reg_w %s(0x%02x) data 0x%02x\n", "UNKNOWN", m_addr, m_reg[m_addr]);
+ else if (std::string(reg_name[m_addr]).empty())
+ LOG("reg_w %s(0x%02x) data 0x%04x\n", reg_name[m_addr - 1], m_addr - 1, u16(m_reg[m_addr - 1]) << 8 | m_reg[m_addr]);
+ else if ((m_addr & 1) || !std::string(reg_name[m_addr + 1]).empty())
+ LOG("reg_w %s(0x%02x) data 0x%02x\n", reg_name[m_addr], m_addr, m_reg[m_addr]);
+ }
+ }
+ else
+ LOG("write unknown register 0x%04x data 0x%02x\n", m_addr, data);
+ m_addr++;
+ break;
+ case XMAP_MODE:
+ m_xmap[m_addr++] = data;
+ break;
+ case EXT_RAM:
+ m_ram[m_addr++ & 0x7fffU] = data;
+ break;
+ case ADDR_LO:
+ m_addr = (m_addr & 0xff00U) | (data << 0);
+ break;
+ case ADDR_HI:
+ m_addr = (m_addr & 0x00ffU) | (data << 8);
+ break;
+ default:
+ LOG("write offset %d data 0x%02x\n", offset, data);
+ break;
+ }
+}
diff --git a/src/mame/sgi/vc1.h b/src/mame/sgi/vc1.h
new file mode 100644
index 00000000000..f20454983c9
--- /dev/null
+++ b/src/mame/sgi/vc1.h
@@ -0,0 +1,32 @@
+// license:BSD-3-Clause
+// copyright-holders:Patrick Mackinlay
+
+#ifndef MAME_SGI_VC1_H
+#define MAME_SGI_VC1_H
+
+#pragma once
+
+class sgi_vc1_device
+ : public device_t
+{
+public:
+ sgi_vc1_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock);
+
+ u8 read(offs_t offset);
+ void write(offs_t offset, u8 data);
+
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+private:
+ u16 m_addr;
+ u8 m_reg[128];
+ u8 m_xmap[128];
+
+ std::unique_ptr<u8[]> m_ram;
+};
+
+DECLARE_DEVICE_TYPE(SGI_VC1, sgi_vc1_device)
+
+#endif // MAME_SGI_VC1_H