From 257ffb502fd960e157de0574aa78049a9566d46d Mon Sep 17 00:00:00 2001 From: angelosa Date: Sun, 6 Aug 2023 17:07:40 +0200 Subject: video/mga2064w.cpp: add mgabase1 accessing alias, identify RAMDAC --- src/devices/video/mga2064w.cpp | 58 +++++++++++++++++++++++-- src/devices/video/mga2064w.h | 11 ++++- src/devices/video/pc_vga_matrox.cpp | 86 ++++++++++++++++++++++++++++++++----- src/devices/video/pc_vga_matrox.h | 9 ++++ 4 files changed, 150 insertions(+), 14 deletions(-) diff --git a/src/devices/video/mga2064w.cpp b/src/devices/video/mga2064w.cpp index c22205e3168..cb271348fcd 100644 --- a/src/devices/video/mga2064w.cpp +++ b/src/devices/video/mga2064w.cpp @@ -3,14 +3,26 @@ #include "emu.h" #include "mga2064w.h" +#define LOG_WARN (1U << 1) +#define LOG_ALIAS (1U << 2) // log mgabase1 index setups thru the back door + +#define VERBOSE (LOG_GENERAL | LOG_WARN | LOG_ALIAS) +//#define LOG_OUTPUT_FUNC osd_printf_info +#include "logmacro.h" + +#define LOGWARN(...) LOGMASKED(LOG_WARN, __VA_ARGS__) +#define LOGALIAS(...) LOGMASKED(LOG_ALIAS, __VA_ARGS__) + DEFINE_DEVICE_TYPE(MGA2064W, mga2064w_device, "mga2064w", "Matrox Millennium \"IS-STORM / MGA-2064W\"") mga2064w_device::mga2064w_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : pci_device(mconfig, MGA2064W, tag, owner, clock) + , device_memory_interface(mconfig, *this) , m_svga(*this, "svga") , m_vga_rom(*this, "vga_rom") { set_ids(0x102b0519, 0x01, 0x030000, 0x00000000); + m_mgabase1_real_space_config = address_space_config("mgabase1_regs", ENDIANNESS_LITTLE, 8, 14, 0, address_map_constructor(FUNC(mga2064w_device::mgabase1_map), this)); } ROM_START( mga2064w ) @@ -47,6 +59,7 @@ void mga2064w_device::device_add_mconfig(machine_config &config) void mga2064w_device::device_start() { pci_device::device_start(); + // NB: following is swapped on G400 add_map( 16*1024, M_MEM, FUNC(mga2064w_device::mgabase1_map)); add_map(8*1024*1024, M_MEM, FUNC(mga2064w_device::mgabase2_map)); // add_rom_from_region(); @@ -60,14 +73,22 @@ void mga2064w_device::device_reset() // INTA# intr_pin = 1; + m_mgabase1_real_index = 0; +} + +device_memory_interface::space_config_vector mga2064w_device::memory_space_config() const +{ + return space_config_vector { + std::make_pair(AS_IO, &m_mgabase1_real_space_config) + }; } void mga2064w_device::config_map(address_map &map) { pci_device::config_map(map); // map(0x40, 0x43) OPTION -// map(0x44, 0x47) MGA_INDEX - aliases for accessing mgabase1 thru PCI config space -// map(0x48, 0x4b) MGA_DATA / + map(0x44, 0x47).rw(FUNC(mga2064w_device::mga_index_r), FUNC(mga2064w_device::mga_index_w)); + map(0x48, 0x4b).rw(FUNC(mga2064w_device::mga_data_r), FUNC(mga2064w_device::mga_data_w)); } void mga2064w_device::mgabase1_map(address_map &map) @@ -116,7 +137,7 @@ void mga2064w_device::mgabase1_map(address_map &map) // map(0x1e54, 0x1e57) OPMODE // map(0x1f00, 0x1fff) VGA CRTC linear I/O map(0x1fb0, 0x1fdf).m(m_svga, FUNC(matrox_vga_device::io_map)); -// map(0x3c00, 0x3c1f) RAMDAC + map(0x3c00, 0x3c1f).m(m_svga, FUNC(matrox_vga_device::ramdac_ext_map)); // map(0x3e00, 0x3fff) EXPDEV Expansion bus } @@ -158,3 +179,34 @@ void mga2064w_device::map_extra(uint64_t memory_window_start, uint64_t memory_wi io_space->install_device(0x03b0, 0x03df, *this, &mga2064w_device::legacy_io_map); } } + +/* + * MGA_INDEX / MGA_DATA + * aliases for accessing mgabase1 thru PCI config space + * i.e. a backdoor for x86 in real mode + */ + +u32 mga2064w_device::mga_index_r() +{ + LOGALIAS("MGA_INDEX read\n"); + return m_mgabase1_real_index & 0x3ffc; +} + +void mga2064w_device::mga_index_w(offs_t offset, u32 data, u32 mem_mask) +{ + // VESA BIOS sets up $3c0a while accessing with mask 0x00ff0000 + // bits 0-1 are reserved and don't respond, assume mistake + LOGALIAS("MGA_INDEX write %08x %08x\n", data, mem_mask); + COMBINE_DATA(&m_mgabase1_real_index); + m_mgabase1_real_index &= 0x3ffc; +} + +u8 mga2064w_device::mga_data_r(offs_t offset) +{ + return space(AS_IO).read_byte(offset + m_mgabase1_real_index); +} + +void mga2064w_device::mga_data_w(offs_t offset, u8 data) +{ + space(AS_IO).write_byte(offset + m_mgabase1_real_index, data); +} diff --git a/src/devices/video/mga2064w.h b/src/devices/video/mga2064w.h index c1371a83aec..9165639e435 100644 --- a/src/devices/video/mga2064w.h +++ b/src/devices/video/mga2064w.h @@ -8,7 +8,7 @@ #include "machine/pci.h" #include "video/pc_vga_matrox.h" -class mga2064w_device : public pci_device { +class mga2064w_device : public pci_device, public device_memory_interface { public: mga2064w_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); @@ -20,6 +20,7 @@ protected: virtual void device_reset() override; virtual void device_add_mconfig(machine_config &config) override; + virtual space_config_vector memory_space_config() const override; virtual const tiny_rom_entry *device_rom_region() const override; @@ -35,6 +36,14 @@ protected: private: u8 vram_r(offs_t offset); void vram_w(offs_t offset, uint8_t data); + + address_space_config m_mgabase1_real_space_config; + u32 mga_index_r(); + void mga_index_w(offs_t offset, u32 data, u32 mem_mask = ~0); + u8 mga_data_r(offs_t offset); + void mga_data_w(offs_t offset, u8 data); + + u32 m_mgabase1_real_index = 0; }; DECLARE_DEVICE_TYPE(MGA2064W, mga2064w_device); diff --git a/src/devices/video/pc_vga_matrox.cpp b/src/devices/video/pc_vga_matrox.cpp index 97f3fdde2c9..ab43443a70b 100644 --- a/src/devices/video/pc_vga_matrox.cpp +++ b/src/devices/video/pc_vga_matrox.cpp @@ -17,9 +17,9 @@ matrox_vga_device::matrox_vga_device(const machine_config &mconfig, const char * device_memory_interface::space_config_vector matrox_vga_device::memory_space_config() const { - auto r = svga_device::memory_space_config(); - r.emplace_back(std::make_pair(EXT_REG, &m_crtcext_space_config)); - return r; + auto r = svga_device::memory_space_config(); + r.emplace_back(std::make_pair(EXT_REG, &m_crtcext_space_config)); + return r; } void matrox_vga_device::device_reset() @@ -53,13 +53,79 @@ void matrox_vga_device::io_3bx_3dx_map(address_map &map) // "CRTCEXT*" void matrox_vga_device::crtcext_map(address_map &map) { -// map(0x00, 0x00) Address Generator Extensions -// map(0x01, 0x01) Horizontal Counter Extensions -// map(0x02, 0x02) Vertical Counter Extensions -// map(0x03, 0x03) Miscellaneous -// map(0x04, 0x04) Memory Page register -// map(0x05, 0x05) Horizontal Video Half Count -// map(0x06, 0x07) +// map(0x00, 0x00) Address Generator Extensions +// map(0x01, 0x01) Horizontal Counter Extensions +// map(0x02, 0x02) Vertical Counter Extensions +// map(0x03, 0x03) Miscellaneous +// CRTCEXT4 Memory Page register + map(0x04, 0x04).lrw8( + NAME([this] (offs_t offset) { return svga.bank_w & 0x7f; }), + NAME([this] (offs_t offset, u8 data) { svga.bank_w = data & 0x7f; }) + ); +// map(0x05, 0x05) Horizontal Video Half Count +// map(0x06, 0x07) // \- $07 is actually checked by VESA test (PC=0xc62bb in rev3), // seems to disable SVGA drawing -> diagnostic check? } + +// RAMDAC +// - paired with a Texas Instruments TVP3026 here -> a superset of INMOS IMSG176/IMSG178 +// - integrated with a superset in G400 at least +void matrox_vga_device::ramdac_ext_map(address_map &map) +{ +// map(0x00, 0x00).rw(FUNC(matrox_vga_device::ramdac_write_index_r), FUNC(matrox_vga_device::ramdac_write_index_w)); +// map(0x01, 0x01).rw(FUNC(matrox_vga_device::ramdac_data_r), FUNC(matrox_vga_device::ramdac_data_w)); +// map(0x02, 0x02).rw(FUNC(matrox_vga_device::ramdac_mask_r), FUNC(matrox_vga_device::ramdac_mask_w)); +// map(0x03, 0x03).rw(FUNC(matrox_vga_device::ramdac_read_index_r), FUNC(matrox_vga_device::ramdac_read_index_w)); +// map(0x04, 0x04) Cursor/Overscan Color Write Index +// map(0x05, 0x05) Cursor/Overscan Color data +// map(0x07, 0x07) Cursor/Overscan Color Read Index +// map(0x09, 0x09) Direct Cursor control + map(0x0a, 0x0a).rw(FUNC(matrox_vga_device::ramdac_ext_indexed_r), FUNC(matrox_vga_device::ramdac_ext_indexed_w)); +// map(0x0b, 0x0b) Cursor RAM data +// map(0x0c, 0x0f) Cursor X/Y positions +// map(0x10, 0x1f) +} + +u8 matrox_vga_device::ramdac_ext_indexed_r() +{ + // Unclear from the docs, according to usage seems to be the write index with no autoincrement + logerror("RAMDAC ext read [%02x]++\n", vga.dac.write_index); + return m_ramdac_mode; +} + +void matrox_vga_device::ramdac_ext_indexed_w(offs_t offset, u8 data) +{ + // TODO: really uses the palette write index, cheating for now + m_ramdac_mode = data; + logerror("RAMDAC ext [%02x]++ %02x\n", vga.dac.write_index, data); + if (!machine().side_effects_disabled()) + vga.dac.write_index ++; + svga.rgb16_en = (data & 0xf8) == 0xf0; +} + +uint8_t matrox_vga_device::mem_r(offs_t offset) +{ + // TODO: MGA mode CRTCEXT3 bit 7 + if (svga.rgb16_en) + return svga_device::mem_linear_r(offset + (svga.bank_w * 0x10000)); + return svga_device::mem_r(offset); +} + +void matrox_vga_device::mem_w(offs_t offset, uint8_t data) +{ + if (svga.rgb16_en) + { + svga_device::mem_linear_w(offset + (svga.bank_w * 0x10000), data); + return; + } + svga_device::mem_w(offset, data); +} + +uint16_t matrox_vga_device::offset() +{ + // TODO: shifts depending on RAMDAC mode + CRTCEXT0 bits 5-4 + if (svga.rgb16_en) + return (vga.crtc.offset << 5); + return svga_device::offset(); +} diff --git a/src/devices/video/pc_vga_matrox.h b/src/devices/video/pc_vga_matrox.h index 6f0b8d710a2..295253c45c1 100644 --- a/src/devices/video/pc_vga_matrox.h +++ b/src/devices/video/pc_vga_matrox.h @@ -15,17 +15,26 @@ class matrox_vga_device : public svga_device public: matrox_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + void ramdac_ext_map(address_map &map); + + virtual uint8_t mem_r(offs_t offset) override; + virtual void mem_w(offs_t offset, uint8_t data) override; protected: virtual void io_3bx_3dx_map(address_map &map) override; virtual void device_reset() override; void crtcext_map(address_map &map); + virtual uint16_t offset() override; private: virtual space_config_vector memory_space_config() const override; address_space_config m_crtcext_space_config; + u8 ramdac_ext_indexed_r(); + void ramdac_ext_indexed_w(offs_t offset, u8 data); + u8 m_crtcext_index = 0; + u8 m_ramdac_mode = 0; }; DECLARE_DEVICE_TYPE(MATROX_VGA, matrox_vga_device) -- cgit v1.2.3