From 467e577ee4b5eec08e73f9e237f8a8557c70991c Mon Sep 17 00:00:00 2001 From: angelosa Date: Sat, 23 Mar 2024 15:18:33 +0100 Subject: machine/mediagx_host: move VGA to own core --- scripts/src/video.lua | 12 ++++++++ src/devices/machine/mediagx_host.cpp | 39 +++++++++++++++--------- src/devices/machine/mediagx_host.h | 10 +++++-- src/devices/video/pc_vga_mediagx.cpp | 57 ++++++++++++++++++++++++++++++++++++ src/devices/video/pc_vga_mediagx.h | 37 +++++++++++++++++++++++ 5 files changed, 138 insertions(+), 17 deletions(-) create mode 100644 src/devices/video/pc_vga_mediagx.cpp create mode 100644 src/devices/video/pc_vga_mediagx.h diff --git a/scripts/src/video.lua b/scripts/src/video.lua index 2b95f647fc6..b002af9c818 100644 --- a/scripts/src/video.lua +++ b/scripts/src/video.lua @@ -895,6 +895,18 @@ if (VIDEOS["PC_VGA_MATROX"]~=null) then } end +-------------------------------------------------- +-- +--@src/devices/video/pc_vga_mediagx.h,VIDEOS["PC_VGA_MEDIAGX"] = true +-------------------------------------------------- + +if (VIDEOS["PC_VGA_MEDIAGX"]~=null) then + files { + MAME_DIR .. "src/devices/video/pc_vga_mediagx.cpp", + MAME_DIR .. "src/devices/video/pc_vga_mediagx.h", + } +end + -------------------------------------------------- -- --@src/devices/video/pc_vga_nvidia.h,VIDEOS["PC_VGA_NVIDIA"] = true diff --git a/src/devices/machine/mediagx_host.cpp b/src/devices/machine/mediagx_host.cpp index 5524473fd70..be781ecec06 100644 --- a/src/devices/machine/mediagx_host.cpp +++ b/src/devices/machine/mediagx_host.cpp @@ -4,10 +4,6 @@ MediaGX host implementation (northbridge) -TODO: -- Currently cheat around software VGA, MediaGX notoriously triggers SMI for every access to - VGA legacy ranges, which is horrible both for emulation purposes and for performance. - **************************************************************************************************/ #include "emu.h" @@ -119,6 +115,7 @@ void mediagx_host_device::device_start() io_offset = 0; m_ram.resize(m_ram_size/4); + m_smm_ram.resize(SMM_SIZE/4); } void mediagx_host_device::device_reset() @@ -143,10 +140,9 @@ void mediagx_host_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_vga, FUNC(vga_device::screen_update)); + screen.set_screen_update(m_vga, FUNC(mediagx_vga_device::screen_update)); - // HACK: needs an interruptible x86 core to even try. - VGA(config, m_vga, 0); + MEDIAGX_VGA(config, m_vga, 0); m_vga->set_screen("screen"); m_vga->set_vram_size(4*1024*1024); } @@ -217,7 +213,8 @@ void mediagx_host_device::map_extra( ); memory_space->install_ram(0x00000000, 0x0009ffff, &m_ram[0x00000000/4]); -// memory_space->install_ram(0x000a0000, 0x000bffff, &m_ram[0x000a0000/4]); + // TODO: BC_XMAP_1, which is always 0 in both astropc and matrix (???) + //memory_space->install_ram(0x000a0000, 0x000bffff, &m_ram[0x000a0000/4]); memory_space->install_device(0x000a0000, 0x000bffff, *this, &mediagx_host_device::legacy_memory_map); io_space->install_device(0x03b0, 0x03df, *this, &mediagx_host_device::legacy_io_map); @@ -261,7 +258,7 @@ void mediagx_host_device::map_extra( if (gx_base) { - LOG("gxbase mapped at %08x\n", gx_base); + LOGMAP("gxbase mapped at %08x\n", gx_base); memory_space->install_device(gx_base, (gx_base) | 0xffffff, *this, &mediagx_host_device::gxbase_map); } } @@ -269,12 +266,22 @@ void mediagx_host_device::map_extra( void mediagx_host_device::gxbase_map(address_map &map) { // 0x001000 scratchpad -// 0x008000 Internal bus I/F Unit + map(0x008000, 0x008003).lrw32( + NAME([this] (offs_t offset) { + return m_bc_dram_top; + }), + NAME([this] (offs_t offset, u32 data, u32 mem_mask) { + LOG("GXBASE+%04x: BC_DRAM_TOP %08x & %08x\n", (offset * 4) + 0x8000, data, mem_mask); + COMBINE_DATA(&m_bc_dram_top); + remap_cb(); + }) + ); map(0x008004, 0x00800f).lrw32( NAME([this] (offs_t offset) { return m_bc_xmap[offset]; }), NAME([this] (offs_t offset, u32 data, u32 mem_mask) { + LOG("GXBASE+%04x: BC_XMAP_%d %08x & %08x\n", (offset * 4) + 0x8004, offset + 1, data, mem_mask); COMBINE_DATA(&m_bc_xmap[offset]); remap_cb(); }) @@ -283,7 +290,11 @@ void mediagx_host_device::gxbase_map(address_map &map) map(0x008300, 0x0083ff).m(*this, FUNC(mediagx_host_device::display_ctrl_map)); // 0x008400 Memory controller // 0x008500 Power Management -// 0x400000 SMM System Code + // SMM System Code + map(0x400000, 0x41ffff).lrw32( + NAME([this] (offs_t offset) { return m_smm_ram[offset]; }), + NAME([this] (offs_t offset, u32 data, u32 mem_mask) { COMBINE_DATA(&m_smm_ram[offset]); }) + ); // 0x800000 GFX memory } @@ -350,15 +361,15 @@ void mediagx_host_device::legacy_memory_map(address_map &map) void mediagx_host_device::legacy_io_map(address_map &map) { - map(0x000, 0x02f).m(m_vga, FUNC(vga_device::io_map)); + map(0x000, 0x02f).m(m_vga, FUNC(mediagx_vga_device::io_map)); } uint8_t mediagx_host_device::vram_r(offs_t offset) { - return downcast(m_vga.target())->mem_r(offset); + return downcast(m_vga.target())->mem_r(offset); } void mediagx_host_device::vram_w(offs_t offset, uint8_t data) { - downcast(m_vga.target())->mem_w(offset, data); + downcast(m_vga.target())->mem_w(offset, data); } diff --git a/src/devices/machine/mediagx_host.h b/src/devices/machine/mediagx_host.h index 22fdf397955..d8cb41445f0 100644 --- a/src/devices/machine/mediagx_host.h +++ b/src/devices/machine/mediagx_host.h @@ -7,7 +7,7 @@ #pragma once #include "pci.h" -#include "video/pc_vga.h" +#include "video/pc_vga_mediagx.h" class mediagx_host_device : public pci_host_device { @@ -44,8 +44,9 @@ private: AS_PCI_IO = 2 }; required_device m_host_cpu; - required_device m_vga; + required_device m_vga; std::vector m_ram; + std::vector m_smm_ram; address_space_config m_superio_space_config; void superio_map(address_map &map); @@ -58,7 +59,9 @@ private: u8 gcr = 0; }m_superio; - int m_ram_size = 0; + u32 m_ram_size = 0; + // FIXME: check size + static constexpr u32 SMM_SIZE = 0x20000; u8 m_pci_control[2]{}; u8 m_pci_arbitration[2]{}; @@ -66,6 +69,7 @@ private: void gfx_pipeline_map(address_map &map); void display_ctrl_map(address_map &map); + u32 m_bc_dram_top = 0; u32 m_bc_xmap[3]{}; void legacy_memory_map(address_map &map); diff --git a/src/devices/video/pc_vga_mediagx.cpp b/src/devices/video/pc_vga_mediagx.cpp new file mode 100644 index 00000000000..ea1a6a3d681 --- /dev/null +++ b/src/devices/video/pc_vga_mediagx.cpp @@ -0,0 +1,57 @@ +// license:BSD-3-Clause +// copyright-holders: Angelo Salese +/************************************************************************************************** + +MediaGX VGA virtual interface + +TODO: +- Currently cheat around software VGA, MediaGX notoriously triggers SMI for every access to + VGA legacy ranges, which is horrible both for emulation purposes and for performance. +- A good benchmark about fixing pc_vga infrastructure: + it connects thru a VGA connector anyway & it has VGA features (DDC, HW cursor, BitBLT) + +**************************************************************************************************/ + +#include "emu.h" +#include "pc_vga_mediagx.h" + +#include "screen.h" + +#define VERBOSE (LOG_GENERAL) +//#define LOG_OUTPUT_FUNC osd_printf_info +#include "logmacro.h" + +DEFINE_DEVICE_TYPE(MEDIAGX_VGA, mediagx_vga_device, "mediagx_vga", "MediaGX Virtual VGA i/f") + +mediagx_vga_device::mediagx_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : svga_device(mconfig, MEDIAGX_VGA, tag, owner, clock) +{ + m_crtc_space_config = address_space_config("crtc_regs", ENDIANNESS_LITTLE, 8, 8, 0, address_map_constructor(FUNC(mediagx_vga_device::crtc_map), this)); +} + +void mediagx_vga_device::device_start() +{ + svga_device::device_start(); +} + +void mediagx_vga_device::device_reset() +{ + svga_device::device_reset(); +} + +void mediagx_vga_device::crtc_map(address_map &map) +{ + svga_device::crtc_map(map); + // astropc.cpp read this at boot, DDC? + map(0x3e, 0x3e).lr8(NAME([] () { return 0xff; })); +} + +uint8_t mediagx_vga_device::mem_r(offs_t offset) +{ + return svga_device::mem_r(offset); +} + +void mediagx_vga_device::mem_w(offs_t offset, uint8_t data) +{ + svga_device::mem_w(offset, data); +} diff --git a/src/devices/video/pc_vga_mediagx.h b/src/devices/video/pc_vga_mediagx.h new file mode 100644 index 00000000000..98542bd8fee --- /dev/null +++ b/src/devices/video/pc_vga_mediagx.h @@ -0,0 +1,37 @@ +// license:BSD-3-Clause +// copyright-holders: Angelo Salese + +#ifndef MAME_VIDEO_PC_VGA_MEDIAGX_H +#define MAME_VIDEO_PC_VGA_MEDIAGX_H + +#pragma once + +#include "video/pc_vga.h" + +#include "screen.h" + + +class mediagx_vga_device : public svga_device +{ +public: + static constexpr feature_type imperfect_features() { return feature::GRAPHICS; } + + mediagx_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + virtual uint8_t mem_r(offs_t offset) override; + virtual void mem_w(offs_t offset, uint8_t data) override; + +protected: + virtual void device_start() override; + virtual void device_reset() override; + + virtual void crtc_map(address_map &map) override; + +// virtual ioport_constructor device_input_ports() const override; + +private: +}; + +DECLARE_DEVICE_TYPE(MEDIAGX_VGA, mediagx_vga_device) + +#endif // MAME_VIDEO_PC_VGA_MEDIAGX_H -- cgit v1.2.3