machine/mediagx_host: prepare for MediaGX virtual VGA hookup

This commit is contained in:
angelosa 2024-03-20 23:19:08 +01:00
parent 93001fa736
commit 935ad2bcb0
7 changed files with 147 additions and 29 deletions

View File

@ -2917,6 +2917,8 @@ if (MACHINES["PCI"]~=null) then
MAME_DIR .. "src/devices/machine/mediagx_cs5530_bridge.h",
MAME_DIR .. "src/devices/machine/mediagx_cs5530_ide.cpp",
MAME_DIR .. "src/devices/machine/mediagx_cs5530_ide.h",
MAME_DIR .. "src/devices/machine/mediagx_cs5530_video.cpp",
MAME_DIR .. "src/devices/machine/mediagx_cs5530_video.h",
MAME_DIR .. "src/devices/machine/mediagx_host.cpp",
MAME_DIR .. "src/devices/machine/mediagx_host.h",
MAME_DIR .. "src/devices/machine/zfmicro_usb.cpp",

View File

@ -0,0 +1,55 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
/**************************************************************************************************
[Cyrix/National Semiconductor/AMD] [MediaGX/Geode] [Cx/CS]5530 VIDEO implementation (XpressGRAPHICS?)
TODO:
- extensions for host display section (GX_BASE+8300h);
**************************************************************************************************/
#include "emu.h"
#include "mediagx_cs5530_video.h"
#define VERBOSE (LOG_GENERAL)
//#define LOG_OUTPUT_FUNC osd_printf_info
#include "logmacro.h"
DEFINE_DEVICE_TYPE(MEDIAGX_CS5530_VIDEO, mediagx_cs5530_video_device, "mediagx_cs5530_video", "MediaGX CS5530 Video Controller")
mediagx_cs5530_video_device::mediagx_cs5530_video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: pci_device(mconfig, MEDIAGX_CS5530_VIDEO, tag, owner, clock)
{
set_ids(0x10780104, 0x00, 0x030000, 0x00);
}
void mediagx_cs5530_video_device::config_map(address_map &map)
{
pci_device::config_map(map);
// map(0x14, 0xff).unmaprw(); // <reserved>
}
void mediagx_cs5530_video_device::io_map(address_map &map)
{
}
void mediagx_cs5530_video_device::device_start()
{
pci_device::device_start();
add_map(4*1024, M_MEM, FUNC(mediagx_cs5530_video_device::io_map));
// no INT pin
}
void mediagx_cs5530_video_device::device_reset()
{
pci_device::device_reset();
command = 0x0000;
command_mask = 0x0003;
status = 0x0280;
}

View File

@ -0,0 +1,29 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
#ifndef MAME_MACHINE_SIS630_VGA_H
#define MAME_MACHINE_SIS630_VGA_H
#pragma once
#include "pci.h"
#include "video/pc_vga.h"
class mediagx_cs5530_video_device : public pci_device
{
public:
mediagx_cs5530_video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
virtual void device_start() override;
virtual void device_reset() override;
virtual void config_map(address_map &map) override;
void io_map(address_map &map);
};
DECLARE_DEVICE_TYPE(MEDIAGX_CS5530_VIDEO, mediagx_cs5530_video_device)
#endif

View File

@ -2,7 +2,11 @@
// copyright-holders: Angelo Salese
/**************************************************************************************************
MediaGX host implementation (northbridge)
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.
**************************************************************************************************/
@ -23,6 +27,7 @@ DEFINE_DEVICE_TYPE(MEDIAGX_HOST, mediagx_host_device, "mediagx_host", "MediaGX X
mediagx_host_device::mediagx_host_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: pci_host_device(mconfig, MEDIAGX_HOST, tag, owner, clock)
, m_host_cpu(*this, finder_base::DUMMY_TAG)
, m_vga(*this, "vga")
{
m_superio_space_config = address_space_config("superio_space", ENDIANNESS_LITTLE, 8, 8, 0, address_map_constructor(FUNC(mediagx_host_device::superio_map), this));
}
@ -134,6 +139,18 @@ void mediagx_host_device::device_reset()
remap_cb();
}
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));
// HACK: needs an interruptible x86 core to even try.
VGA(config, m_vga, 0);
m_vga->set_screen("screen");
m_vga->set_vram_size(16*1024*1024);
}
void mediagx_host_device::config_map(address_map &map)
{
pci_host_device::config_map(map);
@ -201,6 +218,9 @@ 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]);
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);
LOGMAP("Host Remapping table (BC_XMAP_1 %08x BC_XMAP_2 %08x BC_XMAP_3):\n", m_bc_xmap[0], m_bc_xmap[1], m_bc_xmap[2]);
// BC_XMAP_2 & BC_XMAP_3 bits remaps with this arrangement:
@ -266,3 +286,23 @@ void mediagx_host_device::gxbase_map(address_map &map)
// 0x400000 SMM System Code
// 0x800000 GFX memory
}
void mediagx_host_device::legacy_memory_map(address_map &map)
{
map(0x00000, 0x1ffff).rw(FUNC(mediagx_host_device::vram_r), FUNC(mediagx_host_device::vram_w));
}
void mediagx_host_device::legacy_io_map(address_map &map)
{
map(0x000, 0x02f).m(m_vga, FUNC(vga_device::io_map));
}
uint8_t mediagx_host_device::vram_r(offs_t offset)
{
return downcast<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);
}

View File

@ -7,6 +7,7 @@
#pragma once
#include "pci.h"
#include "video/pc_vga.h"
class mediagx_host_device : public pci_host_device
{
@ -28,6 +29,7 @@ public:
protected:
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_add_mconfig(machine_config &config) 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;
@ -42,6 +44,7 @@ private:
AS_PCI_IO = 2
};
required_device<cpu_device> m_host_cpu;
required_device<vga_device> m_vga;
std::vector<uint32_t> m_ram;
address_space_config m_superio_space_config;
@ -62,6 +65,11 @@ private:
void gxbase_map(address_map &map);
u32 m_bc_xmap[3]{};
void legacy_memory_map(address_map &map);
void legacy_io_map(address_map &map);
u8 vram_r(offs_t offset);
void vram_w(offs_t offset, uint8_t data);
};
DECLARE_DEVICE_TYPE(MEDIAGX_HOST, mediagx_host_device)

View File

@ -49,20 +49,16 @@ Notes:
#include "emu.h"
#include "bus/isa/isa_cards.h"
#include "bus/pci/rivatnt.h"
#include "cpu/i386/i386.h"
#include "machine/8042kbdc.h"
#include "machine/mc146818.h"
#include "machine/mediagx_cs5530_bridge.h"
#include "machine/mediagx_cs5530_ide.h"
#include "machine/mediagx_cs5530_video.h"
#include "machine/mediagx_host.h"
#include "machine/pci.h"
#include "machine/zfmicro_usb.h"
#include "screen.h"
#define ENABLE_VGA 0
namespace {
class astropc_state : public driver_device
@ -129,10 +125,6 @@ void astropc_state::astropc(machine_config &config)
MEDIAGX_HOST(config, "pci:00.0", 0, "maincpu", 128*1024*1024);
// TODO: again copied from misc/matrix.cpp, verify usage here
PCI_BRIDGE(config, "pci:01.0", 0, 0x10780000, 0);
#if ENABLE_VGA
// NOTE: most MediaGX boards don't even provide an AGP port, at best you get PCI slots.
PCI_SLOT(config, "pci:01.0:1", pci_cards, 0, 0, 1, 2, 3, "rivatnt").set_fixed(true);
#endif
// "pci:12.0" or "pci:10.0" depending on pin H26 (readable in bridge thru PCI index $44)
mediagx_cs5530_bridge_device &isa(MEDIAGX_CS5530_BRIDGE(config, "pci:12.0", 0, "maincpu", "pci:12.2"));
@ -150,7 +142,7 @@ void astropc_state::astropc(machine_config &config)
ide.irq_sec().set("pci:12.0", FUNC(mediagx_cs5530_bridge_device::pc_irq15_w));
// "pci:12.3" XpressAUDIO
// "pci:12.4" XpressVIDEO
MEDIAGX_CS5530_VIDEO(config, "pci:12.4", 0);
ZFMICRO_USB(config, "pci:13.0", 0);
@ -302,15 +294,15 @@ void astropc_state::init_astropc()
} // anonymous namespace
GAME( 2005, blackbd, 0, astropc, astropc, astropc_state, init_astropc, ROT0, "Astro", "Black Beard (Russia, set 1)", MACHINE_IS_SKELETON )
GAME( 2005?, blackbda, blackbd, astropc, astropc, astropc_state, init_astropc, ROT0, "Astro", "Black Beard (Russia, set 2)", MACHINE_IS_SKELETON )
GAME( 2005, blackbdb, blackbd, astropc, astropc, astropc_state, init_astropc, ROT0, "Astro", "Black Beard (Russia, set 3)", MACHINE_IS_SKELETON )
GAME( 2005, blackbd, 0, astropc, astropc, astropc_state, init_astropc, ROT0, "Astro", "Black Beard (Russia, set 1)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
GAME( 2005?, blackbda, blackbd, astropc, astropc, astropc_state, init_astropc, ROT0, "Astro", "Black Beard (Russia, set 2)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
GAME( 2005, blackbdb, blackbd, astropc, astropc, astropc_state, init_astropc, ROT0, "Astro", "Black Beard (Russia, set 3)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
GAME( 2005, dslayrr, 0, astropc, astropc, astropc_state, init_astropc, ROT0, "Astro", "Dragon Slayer (Russia, v15.B, 2005/08/10)", MACHINE_IS_SKELETON )
GAME( 2006, dslayrra, dslayrr, astropc, astropc, astropc_state, init_astropc, ROT0, "Astro", "Dragon Slayer (Russia, v16.B, 2005/11/10)", MACHINE_IS_SKELETON )
GAME( 2005, dslayrr, 0, astropc, astropc, astropc_state, init_astropc, ROT0, "Astro", "Dragon Slayer (Russia, v15.B, 2005/08/10)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
GAME( 2006, dslayrra, dslayrr, astropc, astropc, astropc_state, init_astropc, ROT0, "Astro", "Dragon Slayer (Russia, v16.B, 2005/11/10)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
GAME( 2004, hawaii, 0, astropc, astropc, astropc_state, init_astropc, ROT0, "Astro", "Hawaii (Russia)", MACHINE_IS_SKELETON )
GAME( 2004, hawaii, 0, astropc, astropc, astropc_state, init_astropc, ROT0, "Astro", "Hawaii (Russia)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
GAME( 2005, oligam, 0, astropc, astropc, astropc_state, init_astropc, ROT0, "Astro", "Olympian Games (Russia)", MACHINE_IS_SKELETON )
GAME( 2005, oligam, 0, astropc, astropc, astropc_state, init_astropc, ROT0, "Astro", "Olympian Games (Russia)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
GAME( 2005, rasce, 0, astropc, astropc, astropc_state, init_astropc, ROT0, "Astro", "Ra's Scepter (Russia)", MACHINE_IS_SKELETON )
GAME( 2005, rasce, 0, astropc, astropc, astropc_state, init_astropc, ROT0, "Astro", "Ra's Scepter (Russia)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )

View File

@ -30,20 +30,16 @@ Unpopulated spaces marked for: DS5002FP, PIC16C54, 93C56 EEPROM, a couple more u
#include "emu.h"
#include "bus/isa/isa_cards.h"
#include "bus/pci/rivatnt.h"
#include "cpu/i386/i386.h"
#include "machine/8042kbdc.h"
#include "machine/mc146818.h"
#include "machine/mediagx_cs5530_bridge.h"
#include "machine/mediagx_cs5530_ide.h"
#include "machine/mediagx_cs5530_video.h"
#include "machine/mediagx_host.h"
#include "machine/pci.h"
#include "machine/zfmicro_usb.h"
#include "screen.h"
#define ENABLE_VGA 0
namespace {
class matrix_state : public driver_device
@ -107,10 +103,6 @@ void matrix_state::matrix(machine_config &config)
// Tries to initialize MediaGX F4 -> ISA -> PCI
// May actually be a ZFMicro PCI Bridge (0x10780400)?
PCI_BRIDGE(config, "pci:01.0", 0, 0x10780000, 0);
#if ENABLE_VGA
// NOTE: most MediaGX boards don't even provide an AGP port, at best you get PCI slots.
PCI_SLOT(config, "pci:01.0:1", pci_cards, 0, 0, 1, 2, 3, "rivatnt").set_fixed(true);
#endif
// "pci:12.0" or "pci:10.0" depending on pin H26 (readable in bridge thru PCI index $44)
mediagx_cs5530_bridge_device &isa(MEDIAGX_CS5530_BRIDGE(config, "pci:12.0", 0, "maincpu", "pci:12.2"));
@ -128,7 +120,7 @@ void matrix_state::matrix(machine_config &config)
ide.irq_sec().set("pci:12.0", FUNC(mediagx_cs5530_bridge_device::pc_irq15_w));
// "pci:12.3" XpressAUDIO
// "pci:12.4" XpressVIDEO
MEDIAGX_CS5530_VIDEO(config, "pci:12.4", 0);
ZFMICRO_USB(config, "pci:13.0", 0);