misc/matrix.cpp: write PCI stubs for MediaGX host & CS5530 bridge

This commit is contained in:
angelosa 2023-12-13 00:36:56 +01:00
parent 5f113c0a9e
commit 0e266f4b43
6 changed files with 335 additions and 12 deletions

View File

@ -2460,6 +2460,30 @@ if (MACHINES["MDCR"]~=null) then
}
end
---------------------------------------------------
--
--@src/devices/machine/mediagx_cs5530_bridge.h,MACHINES["MEDIAGX_CS5530_BRIDGE"] = true
---------------------------------------------------
if (MACHINES["MEDIAGX_CS5530_BRIDGE"]~=null) then
files {
MAME_DIR .. "src/devices/machine/mediagx_cs5530_bridge.cpp",
MAME_DIR .. "src/devices/machine/mediagx_cs5530_bridge.h",
}
end
---------------------------------------------------
--
--@src/devices/machine/mediagx_host.h,MACHINES["MEDIAGX_HOST"] = true
---------------------------------------------------
if (MACHINES["MEDIAGX_HOST"]~=null) then
files {
MAME_DIR .. "src/devices/machine/mediagx_host.cpp",
MAME_DIR .. "src/devices/machine/mediagx_host.h",
}
end
---------------------------------------------------
--
--@src/devices/machine/meters.h,MACHINES["METERS"] = true

View File

@ -0,0 +1,98 @@
// license:BSD-3-Clause
// copyright-holders:Angelo Salese
/**************************************************************************************************
[Cyrix/National Semiconductor/AMD] [MediaGX/Geode] [Cx/CS]5530 bridge implementation (southbridge)
**************************************************************************************************/
#include "emu.h"
#include "mediagx_cs5530_bridge.h"
DEFINE_DEVICE_TYPE(MEDIAGX_CS5530_BRIDGE, mediagx_cs5530_bridge_device, "mediagx_cs5530_bridge", "MediaGX CS5530 Bridge")
mediagx_cs5530_bridge_device::mediagx_cs5530_bridge_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: pci_device(mconfig, MEDIAGX_CS5530_BRIDGE, tag, owner, clock)
// , m_smi_callback(*this)
// , m_nmi_callback(*this)
// , m_stpclk_callback(*this)
, m_boot_state_hook(*this)
, m_maincpu(*this, finder_base::DUMMY_TAG)
// , m_pic8259_master(*this, "pic8259_master")
// , m_pic8259_slave(*this, "pic8259_slave")
// , m_dma8237_1(*this, "dma8237_1")
// , m_dma8237_2(*this, "dma8237_2")
// , m_pit8254(*this, "pit8254")
, m_isabus(*this, "isabus")
// , m_speaker(*this, "speaker")
{
}
void mediagx_cs5530_bridge_device::device_add_mconfig(machine_config &config)
{
ISA16(config, m_isabus, 0);
}
void mediagx_cs5530_bridge_device::device_config_complete()
{
auto isabus = m_isabus.finder_target();
isabus.first.subdevice<isa16_device>(isabus.second)->set_memspace(m_maincpu, AS_PROGRAM);
isabus.first.subdevice<isa16_device>(isabus.second)->set_iospace(m_maincpu, AS_IO);
pci_device::device_config_complete();
}
void mediagx_cs5530_bridge_device::device_reset()
{
pci_device::device_reset();
command = 0x0000;
status = 0x0280;
}
void mediagx_cs5530_bridge_device::config_map(address_map &map)
{
pci_device::config_map(map);
// ...
}
void mediagx_cs5530_bridge_device::internal_io_map(address_map &map)
{
// map(0x0000, 0x001f).rw("dma8237_1", FUNC(am9517a_device::read), FUNC(am9517a_device::write));
// map(0x0020, 0x003f).rw("pic8259_master", FUNC(pic8259_device::read), FUNC(pic8259_device::write));
// map(0x0040, 0x005f).rw("pit8254", FUNC(pit8254_device::read), FUNC(pit8254_device::write));
// map(0x0061, 0x0061).rw(FUNC(mediagx_cs5530_bridge_device::at_portb_r), FUNC(mediagx_cs5530_bridge_device::at_portb_w));
// map(0x0070, 0x0071) RTC
// map(0x0080, 0x009f).rw(FUNC(mediagx_cs5530_bridge_device::at_page8_r), FUNC(mediagx_cs5530_bridge_device::at_page8_w));
// map(0x00a0, 0x00bf).rw("pic8259_slave", FUNC(pic8259_device::read), FUNC(pic8259_device::write));
// map(0x00c0, 0x00df).rw(FUNC(mediagx_cs5530_bridge_device::at_dma8237_2_r), FUNC(mediagx_cs5530_bridge_device::at_dma8237_2_w));
// map(0x04d0, 0x04d1).rw(FUNC(mediagx_cs5530_bridge_device::eisa_irq_read), FUNC(mediagx_cs5530_bridge_device::eisa_irq_write));
map(0x00e0, 0x00ef).noprw();
// map(0x121c, 0x121f) ACPI Timer count register (on rev 1.3+)
}
void mediagx_cs5530_bridge_device::map_bios(address_space *memory_space, uint32_t start, uint32_t end)
{
uint32_t mask = m_region->bytes() - 1;
memory_space->install_rom(start, end, m_region->base() + (start & mask));
}
void mediagx_cs5530_bridge_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)
{
m_isabus->remap(AS_PROGRAM, 0, 1 << 24);
map_bios(memory_space, 0xffffffff - m_region->bytes() + 1, 0xffffffff);
// TODO: BIOS window conditions
map_bios(memory_space, 0x000e0000, 0x000fffff);
m_isabus->remap(AS_IO, 0, 0xffff);
io_space->install_device(0, 0xffff, *this, &mediagx_cs5530_bridge_device::internal_io_map);
}

View File

@ -0,0 +1,54 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
#ifndef MAME_MACHINE_MEDIAGX_CS5530_BRIDGE_H
#define MAME_MACHINE_MEDIAGX_CS5530_BRIDGE_H
#pragma once
#include "pci.h"
#include "mediagx_cs5530_bridge.h"
#include "bus/isa/isa.h"
class mediagx_cs5530_bridge_device : public pci_device
{
public:
template <typename T>
mediagx_cs5530_bridge_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&cpu_tag)
: mediagx_cs5530_bridge_device(mconfig, tag, owner, clock)
{
set_ids(0x10780100, 0x00, 0x060100, 0x00000000);
set_cpu_tag(std::forward<T>(cpu_tag));
}
mediagx_cs5530_bridge_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
auto boot_state_hook() { return m_boot_state_hook.bind(); }
template <typename T>
void set_cpu_tag(T &&tag) { m_maincpu.set_tag(std::forward<T>(tag)); }
protected:
virtual void device_add_mconfig(machine_config & config) override;
virtual void device_config_complete() override;
virtual void device_reset() 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 bool map_first() const override { return true; }
virtual void config_map(address_map &map) override;
private:
void map_bios(address_space *memory_space, uint32_t start, uint32_t end);
void internal_io_map(address_map &map);
devcb_write8 m_boot_state_hook;
required_device<cpu_device> m_maincpu;
required_device<isa16_device> m_isabus;
};
DECLARE_DEVICE_TYPE(MEDIAGX_CS5530_BRIDGE, mediagx_cs5530_bridge_device)
#endif

View File

@ -0,0 +1,94 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
/**************************************************************************************************
MediaGX host implementation (northbridge)
**************************************************************************************************/
#include "emu.h"
#include "mediagx_host.h"
#define VERBOSE (LOG_GENERAL)
//#define LOG_OUTPUT_FUNC osd_printf_warning
#include "logmacro.h"
DEFINE_DEVICE_TYPE(MEDIAGX_HOST, mediagx_host_device, "mediagx_host", "MediaGX X-Bus Host PCI")
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)
{
}
void mediagx_host_device::device_start()
{
pci_host_device::device_start();
memory_window_start = 0;
memory_window_end = 0xffffffff;
memory_offset = 0;
io_window_start = 0;
io_window_end = 0xffff;
io_offset = 0;
memory_space = &m_host_cpu->space(AS_PROGRAM);
io_space = &m_host_cpu->space(AS_IO);
m_ram.resize(m_ram_size/4);
}
void mediagx_host_device::device_reset()
{
pci_host_device::device_reset();
command = 0x0007;
status = 0x0280;
m_pci_control[0] = 0x00;
m_pci_control[1] = 0x96;
m_pci_arbitration[0] = 0x80;
m_pci_arbitration[1] = 0x00;
remap_cb();
}
void mediagx_host_device::config_map(address_map &map)
{
pci_host_device::config_map(map);
map(0x40, 0x41).lrw8(
NAME([this] (offs_t offset) {
LOG("PCI Control Function %d read\n", offset + 1);
return m_pci_control[offset];
}),
NAME([this] (offs_t offset, u8 data) {
LOG("PCI Control Function %d write %02x\n", offset + 1, data);
m_pci_control[offset] = data;
})
);
map(0x43, 0x44).lrw8(
NAME([this] (offs_t offset) {
LOG("PCI Arbitration Control %d read\n", offset + 1);
return m_pci_arbitration[offset];
}),
NAME([this] (offs_t offset, u8 data) {
LOG("PCI Arbitration Control %d write %02x\n", offset + 1, data);
m_pci_arbitration[offset] = data;
})
);
}
void mediagx_host_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
) {
io_space->install_device(0, 0xffff, *static_cast<pci_host_device *>(this), &pci_host_device::io_configuration_access_map);
regenerate_config_mapping();
memory_space->install_ram(0x00000000, 0x0009ffff, &m_ram[0x00000000/4]);
// memory_space->install_ram(0x000a0000, 0x000bffff, &m_ram[0x000a0000/4]);
}

View File

@ -0,0 +1,48 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
#ifndef MAME_MACHINE_MEDIAGX_HOST_H
#define MAME_MACHINE_MEDIAGX_HOST_H
#pragma once
#include "pci.h"
#include "mediagx_host.h"
class mediagx_host_device : public pci_host_device
{
public:
template <typename T> mediagx_host_device(
const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock,
T &&cpu_tag, int ram_size
) : mediagx_host_device(mconfig, tag, owner, clock)
{
set_ids(0x10780001, 0x00, 0x060000, 0x00);
//set_multifunction_device(true);
m_host_cpu.set_tag(std::forward<T>(cpu_tag));
set_ram_size(ram_size);
}
mediagx_host_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
void set_ram_size(int ram_size) { m_ram_size = ram_size; }
protected:
virtual void device_start() override;
virtual void device_reset() 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;
private:
required_device<cpu_device> m_host_cpu;
std::vector<uint32_t> m_ram;
int m_ram_size = 0;
u8 m_pci_control[2]{};
u8 m_pci_arbitration[2]{};
};
DECLARE_DEVICE_TYPE(MEDIAGX_HOST, mediagx_host_device)
#endif

View File

@ -22,7 +22,13 @@
*/
#include "emu.h"
#include "bus/isa/isa_cards.h"
#include "cpu/i386/i386.h"
#include "machine/mediagx_cs5530_bridge.h"
#include "machine/mediagx_host.h"
#include "machine/pci.h"
#include "screen.h"
@ -42,15 +48,11 @@ private:
required_device<cpu_device> m_maincpu;
void main_map(address_map &map);
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { return 0; }
};
void matrix_state::main_map(address_map &map)
{
map(0x000e0000, 0x000fffff).rom().region("bios", 0x20000);
map(0xfffc0000, 0xffffffff).rom().region("bios", 0);
}
static INPUT_PORTS_START( matrix )
@ -63,18 +65,21 @@ void matrix_state::matrix(machine_config &config)
MEDIAGX(config, m_maincpu, 233'000'000); // Cyrix MediaGX GXm-266GP
m_maincpu->set_addrmap(AS_PROGRAM, &matrix_state::main_map);
// video hardware, all TBD
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(60);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
screen.set_size(640, 480);
screen.set_visarea(0, 640-1, 0, 480-1);
screen.set_screen_update(FUNC(matrix_state::screen_update));
PCI_ROOT(config, "pci", 0);
MEDIAGX_HOST(config, "pci:00.0", 0, "maincpu", 128*1024*1024);
// TODO: unconfirmed PCI space
mediagx_cs5530_bridge_device &isa(MEDIAGX_CS5530_BRIDGE(config, "pci:07.0", 0, "maincpu"));
isa.boot_state_hook().set([](u8 data) { /* printf("%02x\n", data); */ });
//isa.smi().set_inputline("maincpu", INPUT_LINE_SMI);
// TODO: unknown number of ISA slots
ISA16_SLOT(config, "isa1", 0, "pci:07.0:isabus", pc_isa16_cards, nullptr, false);
}
ROM_START( matrix )
ROM_REGION32_LE(0x40000, "bios", 0)
ROM_REGION32_LE(0x40000, "pci:07.0", 0)
ROM_LOAD("d586_bios.bin", 0x00000, 0x40000, CRC(39fc093a) SHA1(3376bac4f0d6e729d5939e3078ecdf700464cba3) )
ROM_REGION(0x300000, "unsorted", 0) // encrypted?