machine/mediagx_host: move VGA to own core

This commit is contained in:
angelosa 2024-03-23 15:18:33 +01:00
parent 0d98beb075
commit 467e577ee4
5 changed files with 138 additions and 17 deletions

View File

@ -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

View File

@ -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<vga_device *>(m_vga.target())->mem_r(offset);
return downcast<mediagx_vga_device *>(m_vga.target())->mem_r(offset);
}
void mediagx_host_device::vram_w(offs_t offset, uint8_t data)
{
downcast<vga_device *>(m_vga.target())->mem_w(offset, data);
downcast<mediagx_vga_device *>(m_vga.target())->mem_w(offset, data);
}

View File

@ -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<cpu_device> m_host_cpu;
required_device<vga_device> m_vga;
required_device<mediagx_vga_device> m_vga;
std::vector<uint32_t> m_ram;
std::vector<uint32_t> 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);

View File

@ -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);
}

View File

@ -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