misc/matrix.cpp: add CS5530 IDE PCI block

This commit is contained in:
angelosa 2023-12-17 03:58:32 +01:00
parent 4a1f7b7a2b
commit 3706aabe3d
7 changed files with 320 additions and 33 deletions

View File

@ -2891,6 +2891,8 @@ if (MACHINES["PCI"]~=null) then
MAME_DIR .. "src/devices/machine/vt8231_isa.h",
MAME_DIR .. "src/devices/machine/mediagx_cs5530_bridge.cpp",
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_host.cpp",
MAME_DIR .. "src/devices/machine/mediagx_host.h",
MAME_DIR .. "src/devices/machine/zfmicro_usb.cpp",

View File

@ -11,11 +11,15 @@
#include "speaker.h"
#define VERBOSE (LOG_GENERAL)
#define LOG_MAP (1U << 1) // log full remaps
#define VERBOSE (LOG_GENERAL | LOG_MAP)
//#define LOG_OUTPUT_FUNC osd_printf_warning
#include "logmacro.h"
#define LOGMAP(...) LOGMASKED(LOG_MAP, __VA_ARGS__)
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)
@ -28,6 +32,7 @@ mediagx_cs5530_bridge_device::mediagx_cs5530_bridge_device(const machine_config
, m_rtccs_read(*this, 0xff)
, m_rtccs_write(*this)
, m_host_cpu(*this, finder_base::DUMMY_TAG)
, m_ide(*this, finder_base::DUMMY_TAG)
, m_pic8259_master(*this, "pic8259_master")
, m_pic8259_slave(*this, "pic8259_slave")
, m_dma8237_1(*this, "dma8237_1")
@ -142,6 +147,15 @@ void mediagx_cs5530_bridge_device::config_map(address_map &map)
// map(0x52, 0x52) ROM/AT Logic Control
// map(0x53, 0x53) Alternate CPU Support
// map(0x5a, 0x5b) Decode Control
map(0x5a, 0x5b).lrw8(
NAME([this] (offs_t offset) {
return m_decode_control[offset];
}),
NAME([this] (offs_t offset, u8 data) {
m_decode_control[offset] = data;
remap_cb();
})
);
// map(0x5c, 0x5d) PCI Interrupt Steering
// map(0x70, 0x71) GPCS Base Address
@ -216,7 +230,7 @@ void mediagx_cs5530_bridge_device::internal_io_map(address_map &map)
// TODO: port decoding driven by PCI register $52
map(0x0092, 0x0092).lrw8(
NAME([this] () {
LOG("Fast init $92 read\n");
//LOG("Fast init $92 read\n");
return m_fast_init;
}),
NAME([this] (u8 data) {
@ -487,10 +501,56 @@ void mediagx_cs5530_bridge_device::map_extra(
{
m_isabus->remap(AS_PROGRAM, 0, 1 << 24);
map_bios(memory_space, 0xffffffff - m_region->bytes() + 1, 0xffffffff);
// TODO: BIOS window conditions
// TODO: BIOS window conditions + BIOS ROM
if (BIT(m_decode_control[1], 5))
LOGMAP("BIOS ROM positive decode\n");
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);
if (BIT(m_decode_control[0], 0))
LOGMAP("RTC positive decode $070 & $071\n");
if (BIT(m_decode_control[0], 1))
LOGMAP("KBDC positive decode $060 & $064 (mailbox $62 & $66 %s)\n", BIT(m_decode_control[1], 7) ? "enabled" : "disabled");
if (BIT(m_decode_control[0], 2))
LOGMAP("COM1 positive decode $3f8-$3ff\n");
if (BIT(m_decode_control[0], 3))
LOGMAP("COM2 positive decode $2f8-$2ff\n");
if (BIT(m_decode_control[0], 4))
LOGMAP("COM3 positive decode $3e8-$3ef\n");
if (BIT(m_decode_control[0], 5))
LOGMAP("COM4 positive decode $2e8-$2ef\n");
if (BIT(m_decode_control[0], 6))
LOGMAP("Primary FDC positive decode $3f2-$3f5 & $3f7\n");
if (BIT(m_decode_control[0], 7))
LOGMAP("Secondary FDC positive decode $372-$375 & $377\n");
if (BIT(m_decode_control[1], 0))
LOGMAP("LPT1 positive decode $378-$37f & $778-$77a\n");
if (BIT(m_decode_control[1], 1))
LOGMAP("LPT2 positive decode $278-$27f & $678-$67a\n");
if (BIT(m_decode_control[1], 2))
LOGMAP("LPT3 positive decode $3bc-$3be & $7bc-$7be\n");
if (BIT(m_decode_control[1], 4))
{
LOGMAP("Secondary IDE positive decode $170-$177 & $376-$377\n");
io_space->install_device(0, 0xffff, *m_ide, &mediagx_cs5530_ide_device::secondary_ide_map);
}
if (BIT(m_decode_control[1], 3))
{
LOGMAP("Primary IDE positive decode $1f0-$1f7 & $3f6-$3f7\n");
io_space->install_device(0, 0xffff, *m_ide, &mediagx_cs5530_ide_device::primary_ide_map);
}
}

View File

@ -7,6 +7,7 @@
#pragma once
#include "pci.h"
#include "mediagx_cs5530_ide.h"
#include "bus/isa/isa.h"
#include "cpu/i386/i386.h"
@ -15,15 +16,17 @@
#include "machine/pit8253.h"
#include "sound/spkrdev.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)
template <typename T, typename U>
mediagx_cs5530_bridge_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&cpu_tag, U &&ide_tag)
: mediagx_cs5530_bridge_device(mconfig, tag, owner, clock)
{
set_ids(0x10780100, 0x00, 0x060100, 0x00000000);
set_cpu_tag(std::forward<T>(cpu_tag));
set_ide_tag(std::forward<U>(ide_tag));
}
mediagx_cs5530_bridge_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
@ -33,9 +36,12 @@ public:
auto rtccs_read() { return m_rtccs_read.bind(); }
auto rtccs_write() { return m_rtccs_write.bind(); }
void pc_irq8n_w(int state);
void pc_irq14_w(int state);
void pc_irq15_w(int state);
template <typename T> void set_cpu_tag(T &&tag) { m_host_cpu.set_tag(std::forward<T>(tag)); }
template <typename T> void set_ide_tag(T &&tag) { m_ide.set_tag(std::forward<T>(tag)); }
template <typename T>
void set_cpu_tag(T &&tag) { m_host_cpu.set_tag(std::forward<T>(tag)); }
protected:
virtual void device_add_mconfig(machine_config & config) override;
virtual void device_config_complete() override;
@ -51,7 +57,7 @@ private:
void at_pit8254_out0_changed(int state);
void at_pit8254_out1_changed(int state);
void at_pit8254_out2_changed(int state);
uint8_t pc_dma8237_0_dack_r();
uint8_t pc_dma8237_0_dack_r();
uint8_t pc_dma8237_1_dack_r();
uint8_t pc_dma8237_2_dack_r();
uint8_t pc_dma8237_3_dack_r();
@ -93,8 +99,6 @@ private:
void pc_irq10_w(int state);
void pc_irq11_w(int state);
void pc_irq12m_w(int state);
void pc_irq14_w(int state);
void pc_irq15_w(int state);
void iochck_w(int state);
void pc_select_dma_channel(int channel, bool state);
uint8_t at_page8_r(offs_t offset);
@ -111,6 +115,8 @@ private:
devcb_write8 m_rtccs_write;
required_device<cpu_device> m_host_cpu;
required_device<mediagx_cs5530_ide_device> m_ide;
// southbridge internals
required_device<pic8259_device> m_pic8259_master;
required_device<pic8259_device> m_pic8259_slave;
required_device<am9517a_device> m_dma8237_1;
@ -132,6 +138,7 @@ private:
bool m_nmi_enabled = false;
u8 m_fast_init;
u8 m_decode_control[2]{};
};
DECLARE_DEVICE_TYPE(MEDIAGX_CS5530_BRIDGE, mediagx_cs5530_bridge_device)

View File

@ -0,0 +1,142 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
/**************************************************************************************************
[Cyrix/National Semiconductor/AMD] [MediaGX/Geode] [Cx/CS]5530 IDE implementation
TODO:
- Derive from common pci-ide.cpp interface
**************************************************************************************************/
#include "emu.h"
#include "mediagx_cs5530_ide.h"
#define VERBOSE (LOG_GENERAL)
//#define LOG_OUTPUT_FUNC osd_printf_warning
#include "logmacro.h"
DEFINE_DEVICE_TYPE(MEDIAGX_CS5530_IDE, mediagx_cs5530_ide_device, "mediagx_cs5530_ide", "MediaGX CS5530 IDE Controller")
mediagx_cs5530_ide_device::mediagx_cs5530_ide_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: pci_device(mconfig, MEDIAGX_CS5530_IDE, tag, owner, clock)
, m_ide1(*this, "ide1")
, m_ide2(*this, "ide2")
, m_irq_pri_callback(*this)
, m_irq_sec_callback(*this)
, m_bus_master_space(*this, finder_base::DUMMY_TAG, AS_PROGRAM)
{
}
void mediagx_cs5530_ide_device::device_add_mconfig(machine_config &config)
{
BUS_MASTER_IDE_CONTROLLER(config, m_ide1).options(ata_devices, "hdd", nullptr, false);
m_ide1->irq_handler().set([this](int state) { m_irq_pri_callback(state); });
m_ide1->set_bus_master_space(m_bus_master_space);
BUS_MASTER_IDE_CONTROLLER(config, m_ide2).options(ata_devices, "cdrom", nullptr, false);
m_ide2->irq_handler().set([this](int state) { m_irq_sec_callback(state); });
m_ide2->set_bus_master_space(m_bus_master_space);
}
void mediagx_cs5530_ide_device::config_map(address_map &map)
{
pci_device::config_map(map);
// index 0x24-0xff reserved
}
//
void mediagx_cs5530_ide_device::primary_ide_map(address_map &map)
{
map(0x01f0, 0x01f7).rw(FUNC(mediagx_cs5530_ide_device::ide1_read32_cs0_r), FUNC(mediagx_cs5530_ide_device::ide1_write32_cs0_w));
map(0x03f6, 0x03f6).rw(FUNC(mediagx_cs5530_ide_device::ide1_read_cs1_r), FUNC(mediagx_cs5530_ide_device::ide1_write_cs1_w));
}
void mediagx_cs5530_ide_device::secondary_ide_map(address_map &map)
{
map(0x0170, 0x0177).rw(FUNC(mediagx_cs5530_ide_device::ide2_read32_cs0_r), FUNC(mediagx_cs5530_ide_device::ide2_write32_cs0_w));
map(0x0376, 0x0376).rw(FUNC(mediagx_cs5530_ide_device::ide2_read_cs1_r), FUNC(mediagx_cs5530_ide_device::ide2_write_cs1_w));
}
uint32_t mediagx_cs5530_ide_device::ide1_read32_cs0_r(offs_t offset, uint32_t mem_mask)
{
if (!(command & 1))
return 0xffffffff;
return m_ide1->read_cs0(offset, mem_mask);
}
void mediagx_cs5530_ide_device::ide1_write32_cs0_w(offs_t offset, uint32_t data, uint32_t mem_mask)
{
if (!(command & 1))
return;
m_ide1->write_cs0(offset, data, mem_mask);
}
uint32_t mediagx_cs5530_ide_device::ide2_read32_cs0_r(offs_t offset, uint32_t mem_mask)
{
if (!(command & 1))
return 0xffffffff;
return m_ide2->read_cs0(offset, mem_mask);
}
void mediagx_cs5530_ide_device::ide2_write32_cs0_w(offs_t offset, uint32_t data, uint32_t mem_mask)
{
if (!(command & 1))
return;
m_ide2->write_cs0(offset, data, mem_mask);
}
uint8_t mediagx_cs5530_ide_device::ide1_read_cs1_r()
{
if (!(command & 1))
return 0xff;
return m_ide1->read_cs1(1, 0xff0000) >> 16;
}
void mediagx_cs5530_ide_device::ide1_write_cs1_w(uint8_t data)
{
if (!(command & 1))
return;
m_ide1->write_cs1(1, data << 16, 0xff0000);
}
uint8_t mediagx_cs5530_ide_device::ide2_read_cs1_r()
{
if (!(command & 1))
return 0xff;
return m_ide2->read_cs1(1, 0xff0000) >> 16;
}
void mediagx_cs5530_ide_device::ide2_write_cs1_w(uint8_t data)
{
if (!(command & 1))
return;
m_ide2->write_cs1(1, data << 16, 0xff0000);
}
// F2BAR
void mediagx_cs5530_ide_device::io_map(address_map &map)
{
map(0x00, 0x07).rw(m_ide1, FUNC(bus_master_ide_controller_device::bmdma_r), FUNC(bus_master_ide_controller_device::bmdma_w));
map(0x08, 0x0f).rw(m_ide2, FUNC(bus_master_ide_controller_device::bmdma_r), FUNC(bus_master_ide_controller_device::bmdma_w));
// map(0x20, 0x23).select(0x18) Channel # (bit 5) Drive # (bit 3) PIO
// map(0x24, 0x27).select(0x18) Channel # (bit 5) Drive # (bit 3) DMA Control
}
void mediagx_cs5530_ide_device::device_start()
{
pci_device::device_start();
skip_map_regs(4);
add_map(128, M_IO, FUNC(mediagx_cs5530_ide_device::io_map));
}
void mediagx_cs5530_ide_device::device_reset()
{
pci_device::device_reset();
command = 0x0000;
status = 0x0280;
}

View File

@ -0,0 +1,66 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
#ifndef MAME_MACHINE_MEDIAGX_CS5530_IDE_H
#define MAME_MACHINE_MEDIAGX_CS5530_IDE_H
#pragma once
#include "pci.h"
#include "idectrl.h"
class mediagx_cs5530_ide_device : public pci_device
{
public:
template <typename T> mediagx_cs5530_ide_device(
const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock,
T &&host_tag, uint32_t bmspace = AS_PROGRAM
) : mediagx_cs5530_ide_device(mconfig, tag, owner, clock)
{
set_ids(0x10780102, 0x00, 0x010180, 0x00);
m_bus_master_space.set_tag(host_tag, bmspace);
}
mediagx_cs5530_ide_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
auto irq_pri() { return m_irq_pri_callback.bind(); }
auto irq_sec() { return m_irq_sec_callback.bind(); }
void primary_ide_map(address_map &map);
void secondary_ide_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 void reset_all_mappings() 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:
void io_map(address_map &map);
required_device<bus_master_ide_controller_device> m_ide1;
required_device<bus_master_ide_controller_device> m_ide2;
devcb_write_line m_irq_pri_callback;
devcb_write_line m_irq_sec_callback;
required_address_space m_bus_master_space;
uint32_t ide1_read32_cs0_r(offs_t offset, uint32_t mem_mask = ~0);
void ide1_write32_cs0_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
uint32_t ide2_read32_cs0_r(offs_t offset, uint32_t mem_mask = ~0);
void ide2_write32_cs0_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
uint8_t ide1_read_cs1_r();
void ide1_write_cs1_w(uint8_t data);
uint8_t ide2_read_cs1_r();
void ide2_write_cs1_w(uint8_t data);
};
DECLARE_DEVICE_TYPE(MEDIAGX_CS5530_IDE, mediagx_cs5530_ide_device)
#endif

View File

@ -1,24 +1,30 @@
// license:BSD-3-Clause
// copyright-holders: Angelo Salese
/*
'Matrix' slot machine or poker game (the bezel has poker cards) by unidentified manufacturer
Game title is taken from ROM labels and cabinet. Might be incomplete.
'Matrix' slot machine or poker game (the bezel has poker cards) by unidentified manufacturer
Game title is taken from ROM labels and cabinet. Might be incomplete.
Hardware consists of:
TODO:
- KBDC, not from super I/O;
- Don't recognize an attached HDD, check default CMOS settings;
- loops at PC=eda2d, reads the NMI vector;
- game roms looks encrypted or bad, may require a missing boot device;
Motherboard (GXM-530D): (ETA: BIOS boots as SuperTek ST-MGXm3HB, is 530 actually referring to SiS530? -AS)
Cyrix MediaGX GXm-266GP 2.9V
Cyrix GXm Cx5530 with GCT bios
128MB RAM
SMC FDC37C931
5-dip bank
Hardware consists of:
Daughter card (FLASH ROM SSD 374-525-627-33-78J54):
Lattice ispLSI 1032E 70LJ D980B06
Unpopulated spaces marked for: DS5002FP, PIC16C54, 93C56 EEPROM, a couple more unreadable
8-dip bank
6 ROMs
1 RAM
Motherboard (GXM-530D): (ETA: BIOS boots as SuperTek ST-MGXm3HB, is 530 actually referring to SiS530? -AS)
Cyrix MediaGX GXm-266GP 2.9V
Cyrix GXm Cx5530 with GCT bios
128MB RAM
SMC FDC37C931
5-dip bank
Daughter card (FLASH ROM SSD 374-525-627-33-78J54):
Lattice ispLSI 1032E 70LJ D980B06
Unpopulated spaces marked for: DS5002FP, PIC16C54, 93C56 EEPROM, a couple more unreadable
8-dip bank
6 ROMs
1 RAM
*/
#include "emu.h"
@ -27,6 +33,7 @@
#include "cpu/i386/i386.h"
#include "machine/mc146818.h"
#include "machine/mediagx_cs5530_bridge.h"
#include "machine/mediagx_cs5530_ide.h"
#include "machine/mediagx_host.h"
#include "machine/pci.h"
#include "machine/zfmicro_usb.h"
@ -81,13 +88,13 @@ void matrix_state::matrix(machine_config &config)
PCI_ROOT(config, "pci", 0);
MEDIAGX_HOST(config, "pci:00.0", 0, "maincpu", 128*1024*1024);
// TODO: no clue about the ID used for this, definitely tested
// Tries to initialize MediaGX F4 -> ISA -> PCI/AGP, failing in all cases
// Tries to initialize MediaGX F4 -> ISA -> PCI/AGP
// May actually be a ZFMicro PCI Bridge (0x10780400)?
PCI_BRIDGE(config, "pci:01.0", 0, 0x10780000, 0);
//RIVATNT(config, "pci:01.0:00.0", 0);
// "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"));
mediagx_cs5530_bridge_device &isa(MEDIAGX_CS5530_BRIDGE(config, "pci:12.0", 0, "maincpu", "pci:12.2"));
isa.boot_state_hook().set([](u8 data) { /* printf("%02x\n", data); */ });
//isa.smi().set_inputline("maincpu", INPUT_LINE_SMI);
isa.rtcale().set([this](u8 data) { m_rtc->address_w(data); });
@ -95,11 +102,14 @@ void matrix_state::matrix(machine_config &config)
isa.rtccs_write().set([this](u8 data) { m_rtc->data_w(data); });
// "pci:12.1" SMI & ACPI
// "pci:12.2" IDE
mediagx_cs5530_ide_device &ide(MEDIAGX_CS5530_IDE(config, "pci:12.2", 0, "maincpu"));
ide.irq_pri().set("pci:12.0", FUNC(mediagx_cs5530_bridge_device::pc_irq14_w));
ide.irq_sec().set("pci:12.0", FUNC(mediagx_cs5530_bridge_device::pc_irq15_w));
// "pci:12.3" XpressAUDIO
// "pci:12.4" XpressVIDEO
// "pci:13.0" (different) 0x0e11a0f8 ZF Micro Chipset USB (Compaq OpenHCI)
ZFMICRO_USB(config, "pci:13.0", 0);
// 2 PCI slots, 2 ISA slots

View File

@ -223,12 +223,12 @@ void sis630_state::sis630(machine_config &config)
m_ide_00_1->irq_sec().set("pci:01.0:pic_slave", FUNC(pic8259_device::ir7_w));
//FUNC(sis950_lpc_device::pc_mirq0_w));
SIS950_LPC (config, m_lpc_01_0, XTAL(33'000'000), "maincpu", "flash");
SIS950_LPC(config, m_lpc_01_0, XTAL(33'000'000), "maincpu", "flash");
m_lpc_01_0->fast_reset_cb().set([this] (int state) {
if (state)
machine().schedule_soft_reset();
});
LPC_ACPI (config, "pci:01.0:acpi", 0);
LPC_ACPI(config, "pci:01.0:acpi", 0);
SIS950_SMBUS(config, "pci:01.0:smbus", 0);
SIS900_ETH(config, "pci:01.1", 0);