From f640bd1d6c4d53b8b5c23b513845d69abe6819b2 Mon Sep 17 00:00:00 2001 From: angelosa Date: Sun, 6 Aug 2023 02:48:58 +0200 Subject: [PATCH] video/mga2064w.cpp: add base infrastructure --- scripts/src/video.lua | 36 ++++--- src/devices/video/mga2064w.cpp | 144 +++++++++++++++++++++++++++- src/devices/video/mga2064w.h | 23 ++++- src/devices/video/pc_vga_matrox.cpp | 65 +++++++++++++ src/devices/video/pc_vga_matrox.h | 33 +++++++ 5 files changed, 283 insertions(+), 18 deletions(-) create mode 100644 src/devices/video/pc_vga_matrox.cpp create mode 100644 src/devices/video/pc_vga_matrox.h diff --git a/scripts/src/video.lua b/scripts/src/video.lua index b01fab7ebe5..13c113230e5 100644 --- a/scripts/src/video.lua +++ b/scripts/src/video.lua @@ -341,18 +341,6 @@ if (VIDEOS["GF7600GS"]~=null) then } end --------------------------------------------------- --- ---@src/devices/video/mga2064w.h,VIDEOS["MGA2064W"] = true --------------------------------------------------- - -if (VIDEOS["MGA2064W"]~=null) then - files { - MAME_DIR .. "src/devices/video/mga2064w.cpp", - MAME_DIR .. "src/devices/video/mga2064w.h", - } -end - -------------------------------------------------- -- --@src/devices/video/nt7534.h,VIDEOS["NT7534"] = true @@ -917,6 +905,30 @@ if (VIDEOS["PC_VGA_CIRRUS"]~=null) then } end +-------------------------------------------------- +-- +--@src/devices/video/pc_vga_matrox.h,VIDEOS["PC_VGA_MATROX"] = true +-------------------------------------------------- + +if (VIDEOS["PC_VGA_MATROX"]~=null) then + files { + MAME_DIR .. "src/devices/video/pc_vga_matrox.cpp", + MAME_DIR .. "src/devices/video/pc_vga_matrox.h", + } +end + +-------------------------------------------------- +-- +--@src/devices/video/mga2064w.h,VIDEOS["MGA2064W"] = true +-------------------------------------------------- + +if (VIDEOS["MGA2064W"]~=null) then + files { + MAME_DIR .. "src/devices/video/mga2064w.cpp", + MAME_DIR .. "src/devices/video/mga2064w.h", + } +end + -------------------------------------------------- -- --@src/devices/video/pc_vga_nvidia.h,VIDEOS["PC_VGA_NVIDIA"] = true diff --git a/src/devices/video/mga2064w.cpp b/src/devices/video/mga2064w.cpp index 6654aa9ec2e..c22205e3168 100644 --- a/src/devices/video/mga2064w.cpp +++ b/src/devices/video/mga2064w.cpp @@ -1,26 +1,160 @@ // license:BSD-3-Clause -// copyright-holders:Olivier Galibert +// copyright-holders:Olivier Galibert, Angelo Salese #include "emu.h" #include "mga2064w.h" -DEFINE_DEVICE_TYPE(MGA2064W, mga2064w_device, "mga2064w", "Matrox Millennium") +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) + , m_svga(*this, "svga") + , m_vga_rom(*this, "vga_rom") { set_ids(0x102b0519, 0x01, 0x030000, 0x00000000); } +ROM_START( mga2064w ) + ROM_REGION32_LE( 0x10000, "vga_rom", ROMREGION_ERASEFF ) + ROM_SYSTEM_BIOS( 0, "rev3", "Matrox Power Graphics Accelerator V2.4 IS-MGA-2064W R3" ) + ROMX_LOAD( "rev3.bin", 0x000000, 0x010000, CRC(cb623dab) SHA1(4dc10755613a8fa9599331d78995cfb15145440b), ROM_BIOS(0) ) + // TODO: verify label naming for these + ROM_SYSTEM_BIOS( 1, "rev2", "Matrox Power Graphics Accelerator V1.9 IS-MGA-2064W R2 2MB" ) + ROMX_LOAD( "rev2_2mb.bin", 0x000000, 0x010000, CRC(253c352b) SHA1(a5cd7e1c4903fcc89ea04cc1911b8d010e6513d1), ROM_BIOS(1) ) + ROM_SYSTEM_BIOS( 2, "rev2_storm", "Matrox Power Graphics Accelerator V1.9 IS-STORM R2 (vbi)" ) + ROMX_LOAD( "rev2_storm4mb.vbi", 0x000000, 0x008000, CRC(35660abe) SHA1(36ec630507548e1ef5fa7fdd07852d936fb614e5), ROM_BIOS(2) ) + ROM_SYSTEM_BIOS( 3, "rev2_isstorm", "Matrox Power Graphics Accelerator V1.9 IS-STORM R2" ) + ROMX_LOAD( "matroxisstormr2.bin", 0x000000, 0x010000, CRC(0cfceda4) SHA1(26a4fe291c738b4b138b522beb37b7db1b639634), ROM_BIOS(3) ) + ROM_SYSTEM_BIOS( 4, "rev2_r2", "Matrox Power Graphics Accelerator V1.9 IS-MGA-2064W R2" ) + ROMX_LOAD( "matrox2064wr2.bin", 0x000000, 0x010000, CRC(79920e74) SHA1(d62d6a57c75f2266e3d0f85916f366d62ad56ce4), ROM_BIOS(4) ) +ROM_END + +const tiny_rom_entry *mga2064w_device::device_rom_region() const +{ + return ROM_NAME(mga2064w); +} + +void mga2064w_device::device_add_mconfig(machine_config &config) +{ + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); + screen.set_raw(XTAL(25'174'800), 900, 0, 640, 526, 0, 480); + screen.set_screen_update(m_svga, FUNC(matrox_vga_device::screen_update)); + + MATROX_VGA(config, m_svga, 0); + m_svga->set_screen("screen"); + m_svga->set_vram_size(8*1024*1024); +} + void mga2064w_device::device_start() { pci_device::device_start(); - // add_map( 16*1024*1024, M_MEM, FUNC(mga2064w_device::map1)); - // add_map(256*1024*1024, M_MEM, FUNC(mga2064w_device::map2)); - // add_map( 16*1024*1024, M_MEM, FUNC(mga2064w_device::map3)); + 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(); + + add_rom((u8 *)m_vga_rom->base(), 0x10000); } void mga2064w_device::device_reset() { pci_device::device_reset(); + + // INTA# + intr_pin = 1; +} + +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 / +} + +void mga2064w_device::mgabase1_map(address_map &map) +{ +// map(0x0000, 0x1bff).rw(FUNC(mga2064w_device::dmawin_iload_r), FUNC(mga2064w_device::dmawin_idump_w)); +// map(0x1c00, 0x1cff).mirror(0x100).m(FUNC(mga2064w_device::dwgreg_map); +// map(0x1c00, 0x1c03) DWGCTL +// map(0x1c04, 0x1c07) MACCESS +// map(0x1c08, 0x1c0b) MCTLWTST +// map(0x1c0c, 0x1c0f) ZORG +// map(0x1c10, 0x1c13) PAT0 +// map(0x1c14, 0x1c17) PAT1 +// map(0x1c1c, 0x1c1f) PLNWT +// map(0x1c20, 0x1c23) BCOL +// map(0x1c24, 0x1c27) FCOL +// map(0x1c2c, 0x1c2f) SRCBLT +// map(0x1c30, 0x1c3f) SRC0-3 +// map(0x1c40, 0x1c43) XYSTRT +// map(0x1c44, 0x1c47) XYEND +// map(0x1c50, 0x1c53) SHIFT +// map(0x1c58, 0x1c5b) SGN +// map(0x1c5c, 0x1c5f) LEN +// map(0x1c60, 0x1c7b) AR0-6 +// map(0x1c80, 0x1c83) CXBNDRY +// map(0x1c84, 0x1c87) FXBNDRY +// map(0x1c88, 0x1c8b) YDSTLEN +// map(0x1c8c, 0x1c8f) PITCH +// map(0x1c90, 0x1c93) YDST +// map(0x1c94, 0x1c97) YDSTORG +// map(0x1c98, 0x1c9b) YTOP +// map(0x1c9c, 0x1c9f) YBOT +// map(0x1ca0, 0x1ca3) CXLEFT +// map(0x1ca4, 0x1ca7) CXRIGHT +// map(0x1ca8, 0x1cab) FXLEFT +// map(0x1cac, 0x1caf) FXRIGHT +// map(0x1cb0, 0x1cb3) XDST +// map(0x1cc0, 0x1cff) DR0-DR15 (DR1-5-9-13 ) + +// map(0x1e00, 0x1eff) HSTREG Host registers +// map(0x1e10, 0x1e13) FIFOSTATUS (r/o) +// map(0x1e14, 0x1e17) Status (r/o) +// map(0x1e18, 0x1e1b) ICLEAR +// map(0x1e1c, 0x1e1f) IEN +// map(0x1e20, 0x1e23) VCOUNT (r/o) +// map(0x1e40, 0x1e43) Reset +// 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(0x3e00, 0x3fff) EXPDEV Expansion bus +} + +void mga2064w_device::mgabase2_map(address_map &map) +{ + map(0x000000, 0x7fffff).rw(m_svga, FUNC(matrox_vga_device::mem_linear_r), FUNC(matrox_vga_device::mem_linear_w)); +} + + +// TODO: this should really be a subclass of VGA +void mga2064w_device::legacy_memory_map(address_map &map) +{ + map(0xa0000, 0xbffff).rw(FUNC(mga2064w_device::vram_r), FUNC(mga2064w_device::vram_w)); +} + +// TODO: card may not even support MDA access +void mga2064w_device::legacy_io_map(address_map &map) +{ + map(0, 0x02f).m(m_svga, FUNC(matrox_vga_device::io_map)); +} + +uint8_t mga2064w_device::vram_r(offs_t offset) +{ + return downcast(m_svga.target())->mem_r(offset); +} + +void mga2064w_device::vram_w(offs_t offset, uint8_t data) +{ + downcast(m_svga.target())->mem_w(offset, data); +} + +void mga2064w_device::map_extra(uint64_t memory_window_start, uint64_t memory_window_end, uint64_t memory_offset, address_space *memory_space, + uint64_t io_window_start, uint64_t io_window_end, uint64_t io_offset, address_space *io_space) +{ + // TODO: both can be disabled thru config options + { + memory_space->install_readwrite_handler(0xa0000, 0xbffff, read8sm_delegate(*this, FUNC(mga2064w_device::vram_r)), write8sm_delegate(*this, FUNC(mga2064w_device::vram_w))); + + io_space->install_device(0x03b0, 0x03df, *this, &mga2064w_device::legacy_io_map); + } } diff --git a/src/devices/video/mga2064w.h b/src/devices/video/mga2064w.h index 6766bf304a9..c1371a83aec 100644 --- a/src/devices/video/mga2064w.h +++ b/src/devices/video/mga2064w.h @@ -1,19 +1,40 @@ // license:BSD-3-Clause -// copyright-holders:Olivier Galibert +// copyright-holders:Olivier Galibert, Angelo Salese #ifndef MAME_VIDEO_MGA2064W_H #define MAME_VIDEO_MGA2064W_H #pragma once #include "machine/pci.h" +#include "video/pc_vga_matrox.h" class mga2064w_device : public pci_device { public: mga2064w_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + void legacy_memory_map(address_map &map); + void legacy_io_map(address_map &map); + protected: virtual void device_start() override; virtual void device_reset() override; + + virtual void device_add_mconfig(machine_config &config) override; + + virtual const tiny_rom_entry *device_rom_region() const override; + + virtual void map_extra(uint64_t memory_window_start, uint64_t memory_window_end, uint64_t memory_offset, address_space *memory_space, + uint64_t io_window_start, uint64_t io_window_end, uint64_t io_offset, address_space *io_space) override; + virtual void config_map(address_map &map) override; + + void mgabase1_map(address_map &map); + void mgabase2_map(address_map &map); + + required_device m_svga; + required_memory_region m_vga_rom; +private: + u8 vram_r(offs_t offset); + void vram_w(offs_t offset, uint8_t data); }; DECLARE_DEVICE_TYPE(MGA2064W, mga2064w_device); diff --git a/src/devices/video/pc_vga_matrox.cpp b/src/devices/video/pc_vga_matrox.cpp new file mode 100644 index 00000000000..97f3fdde2c9 --- /dev/null +++ b/src/devices/video/pc_vga_matrox.cpp @@ -0,0 +1,65 @@ +// license:BSD-3-Clause +// copyright-holders:Angelo Salese + +#include "emu.h" +#include "pc_vga_matrox.h" + +DEFINE_DEVICE_TYPE(MATROX_VGA, matrox_vga_device, "matrox_vga", "Matrox MGA2064W VGA") + +matrox_vga_device::matrox_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : svga_device(mconfig, MATROX_VGA, tag, owner, clock) +{ + m_main_if_space_config = address_space_config("io_regs", ENDIANNESS_LITTLE, 8, 4, 0, address_map_constructor(FUNC(matrox_vga_device::io_3bx_3dx_map), this)); + // 3 bits of address space? + m_crtcext_space_config = address_space_config("crtcext_regs", ENDIANNESS_LITTLE, 8, 8, 0, address_map_constructor(FUNC(matrox_vga_device::crtcext_map), this)); + // TODO: docs mentions using 0x22 / 0x24 / 0x26 for regular CRTC (coming from plain VGA?) +} + +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; +} + +void matrox_vga_device::device_reset() +{ + svga_device::device_reset(); + + m_crtcext_index = 0; +} + +void matrox_vga_device::io_3bx_3dx_map(address_map &map) +{ + svga_device::io_3bx_3dx_map(map); + map(0x0e, 0x0e).lrw8( + NAME([this] (offs_t offset) { + return m_crtcext_index; + }), + NAME([this] (offs_t offset, u8 data) { + m_crtcext_index = data; + }) + ); + map(0x0f, 0x0f).lrw8( + NAME([this] (offs_t offset) { + return space(EXT_REG).read_byte(m_crtcext_index); + }), + NAME([this] (offs_t offset, u8 data) { + space(EXT_REG).write_byte(m_crtcext_index, data); + }) + ); +} + +// "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) +// \- $07 is actually checked by VESA test (PC=0xc62bb in rev3), +// seems to disable SVGA drawing -> diagnostic check? +} diff --git a/src/devices/video/pc_vga_matrox.h b/src/devices/video/pc_vga_matrox.h new file mode 100644 index 00000000000..6f0b8d710a2 --- /dev/null +++ b/src/devices/video/pc_vga_matrox.h @@ -0,0 +1,33 @@ +// license:BSD-3-Clause +// copyright-holders:Angelo Salese + +#ifndef MAME_VIDEO_PC_VGA_MATROX_H +#define MAME_VIDEO_PC_VGA_MATROX_H + +#pragma once + +#include "video/pc_vga.h" + +#include "screen.h" + +class matrox_vga_device : public svga_device +{ +public: + matrox_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + virtual void io_3bx_3dx_map(address_map &map) override; + + virtual void device_reset() override; + + void crtcext_map(address_map &map); +private: + virtual space_config_vector memory_space_config() const override; + + address_space_config m_crtcext_space_config; + u8 m_crtcext_index = 0; +}; + +DECLARE_DEVICE_TYPE(MATROX_VGA, matrox_vga_device) + +#endif // MAME_VIDEO_PC_VGA_MATROX_H