From a5c5d21c09564431bb6d7ed137c52b2d656df9e8 Mon Sep 17 00:00:00 2001 From: AJR Date: Sat, 6 Apr 2024 13:46:48 -0400 Subject: [PATCH] qbus: Add dump of Matrox QG-640 Color Display Processor Card and skeleton device implementation [AJR, Bitsavers] --- scripts/src/bus.lua | 2 + src/devices/bus/qbus/qbus.cpp | 6 +- src/devices/bus/qbus/qg640.cpp | 106 +++++++++++++++++++++++++++++++++ src/devices/bus/qbus/qg640.h | 54 +++++++++++++++++ 4 files changed, 166 insertions(+), 2 deletions(-) create mode 100644 src/devices/bus/qbus/qg640.cpp create mode 100644 src/devices/bus/qbus/qg640.h diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 4bd51a77699..5fc56dcc05a 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -4625,6 +4625,8 @@ if (BUSES["QBUS"]~=null) then MAME_DIR .. "src/devices/bus/qbus/pc11.h", MAME_DIR .. "src/devices/bus/qbus/qbus.cpp", MAME_DIR .. "src/devices/bus/qbus/qbus.h", + MAME_DIR .. "src/devices/bus/qbus/qg640.cpp", + MAME_DIR .. "src/devices/bus/qbus/qg640.h", MAME_DIR .. "src/devices/bus/qbus/qtx.cpp", MAME_DIR .. "src/devices/bus/qbus/qtx.h", } diff --git a/src/devices/bus/qbus/qbus.cpp b/src/devices/bus/qbus/qbus.cpp index 82379c071f0..7a375ad9032 100644 --- a/src/devices/bus/qbus/qbus.cpp +++ b/src/devices/bus/qbus/qbus.cpp @@ -12,10 +12,11 @@ // Peripheral boards #include "dsd4432.h" -#include "pc11.h" -#include "qtx.h" #include "dvk_kgd.h" #include "dvk_mx.h" +#include "pc11.h" +#include "qg640.h" +#include "qtx.h" void qbus_cards(device_slot_interface &device) @@ -25,6 +26,7 @@ void qbus_cards(device_slot_interface &device) device.option_add("dsd4432", DSD4432); device.option_add("kgd", DVK_KGD); device.option_add("mx", DVK_MX); + device.option_add("qg640", MATROX_QG640); } diff --git a/src/devices/bus/qbus/qg640.cpp b/src/devices/bus/qbus/qg640.cpp new file mode 100644 index 00000000000..785f4b4ebe2 --- /dev/null +++ b/src/devices/bus/qbus/qg640.cpp @@ -0,0 +1,106 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/********************************************************************** + + Matrox QG-640 640×480×8 graphics card (skeleton) + +**********************************************************************/ + +#include "emu.h" +#include "qg640.h" + +#include "cpu/ns32000/ns32000.h" +#include "screen.h" + +// device type definition +DEFINE_DEVICE_TYPE(MATROX_QG640, qg640_device, "qg640", "Matrox QG-640 Color Display Processor Card") + +qg640_device::qg640_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, MATROX_QG640, tag, owner, clock) + , device_qbus_card_interface(mconfig, *this) + , m_qgcpu(*this, "qgcpu") + , m_fifo(*this, "fifo") + , m_acrtc(*this, "acrtc") + , m_clut(*this, "clut%u", 1U) +{ +} + +void qg640_device::device_start() +{ +} + +u32 qg640_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + return 0; +} + +u8 qg640_device::status_r() +{ + return 0; +} + +void qg640_device::unknown_w(u8 data) +{ + logerror("%s: unknown_w 0x%02X\n", machine().describe_context(), data); +} + +void qg640_device::clut_w(offs_t offset, u8 data) +{ + m_clut[BIT(offset, 18)]->write(BIT(offset, 16, 2), data); +} + +u16 qg640_device::acrtc_r(offs_t offset) +{ + return m_acrtc->read16(!BIT(offset, 17)); +} + +void qg640_device::acrtc_w(offs_t offset, u16 data) +{ + m_acrtc->write16(!BIT(offset, 17), data); +} + +void qg640_device::mem_map(address_map &map) +{ + map(0x000000, 0x01ffff).rom().region("firmware", 0); + map(0x400000, 0x400000).r(FUNC(qg640_device::status_r)); + map(0x500000, 0x500000).w(FUNC(qg640_device::unknown_w)); + map(0x600000, 0x600000).select(0x70000).w(FUNC(qg640_device::clut_w)); + map(0x780000, 0x780001).select(0x40000).rw(FUNC(qg640_device::acrtc_r), FUNC(qg640_device::acrtc_w)); + map(0xc00000, 0xc1ffff).ram(); // 4x OKI M41464-12 +} + +void qg640_device::videoram_map(address_map &map) +{ + map(0x00000, 0x7ffff).ram(); // 10x HM53461P-12 +} + +void qg640_device::device_add_mconfig(machine_config &config) +{ + NS32016(config, m_qgcpu, 18.432_MHz_XTAL / 2); // NS32016N-10 + NS32C201D-10C + m_qgcpu->set_addrmap(AS_PROGRAM, &qg640_device::mem_map); + + IDT7201(config, m_fifo); + + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); + screen.set_raw(50_MHz_XTAL / 2, 816, 0, 640, 510, 0, 480); // 25 MHz pixel clock, 30.63 kHz horizontal, 60.07 Hz vertical + screen.set_screen_update(FUNC(qg640_device::screen_update)); + + HD63484(config, m_acrtc, 50_MHz_XTAL / 8); // SCC63484C8N64; divider unknown + m_acrtc->set_screen("screen"); + m_acrtc->set_addrmap(0, &qg640_device::videoram_map); + + BT471(config, m_clut[0], 0); // IMSG170P-35 + BT471(config, m_clut[1], 0); // IMSG170P-35 +} + +ROM_START(qg640) + ROM_REGION16_LE(0x20000, "firmware", 0) + // "COPYRIGHT (C) 1985 Matrox Electronics, Ltd." (agrees with board copyright date; EPROMs and most other ICs have 1989 date codes, however) + ROM_LOAD16_BYTE("504-8.bin", 0x00000, 0x10000, CRC(213c5804) SHA1(6ab86aeda47d148dd85a548ef716c98b61c53a1a)) // TMS27C512JL + ROM_LOAD16_BYTE("505-8.bin", 0x00001, 0x10000, CRC(73610833) SHA1(815b195c37ca1053e5cddfa1efd4764c4550f4b5)) // TMS27C512JL +ROM_END + +const tiny_rom_entry *qg640_device::device_rom_region() const +{ + return ROM_NAME(qg640); +} diff --git a/src/devices/bus/qbus/qg640.h b/src/devices/bus/qbus/qg640.h new file mode 100644 index 00000000000..30cd93ca0ce --- /dev/null +++ b/src/devices/bus/qbus/qg640.h @@ -0,0 +1,54 @@ +// license:BSD-3-Clause +// copyright-holders:AJR + +#ifndef MAME_BUS_QBUS_QG640_H +#define MAME_BUS_QBUS_QG640_H + +#pragma once + +#include "qbus.h" +#include "machine/7200fifo.h" +#include "video/bt47x.h" +#include "video/hd63484.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> qg640_device + +class qg640_device : public device_t, public device_qbus_card_interface +{ +public: + // device type constructor + qg640_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_add_mconfig(machine_config &config) override; + virtual const tiny_rom_entry *device_rom_region() const override; + +private: + u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + + u8 status_r(); + void unknown_w(u8 data); + void clut_w(offs_t offset, u8 data); + u16 acrtc_r(offs_t offset); + void acrtc_w(offs_t offset, u16 data); + + void mem_map(address_map &map); + void videoram_map(address_map &map); + + required_device m_qgcpu; + required_device m_fifo; + required_device m_acrtc; + required_device_array m_clut; +}; + +// device type declaration +DECLARE_DEVICE_TYPE(MATROX_QG640, qg640_device) + +#endif // MAME_BUS_QBUS_QG640_H