Initial work towards i440bx chipset (#11037)

- implement stubs for i82443bx_host and i82371eb PCI devices, hooks up base PCI stubs to midway/midqslvr.cpp, misc/comebaby.cpp and misc/xtom3d.cpp
- misc/xtom3d.cpp: preliminary implementation of Oksan ROM DISK ISA card
- machine/pci-smbus.h: make map public so it can be reused by i82371eb_acpi (would otherwise fail mapping to the intended HW)

New systems marked not working
----------------------------------
Pump It Up: The 1st Dance Floor [ATR4X, Gergc, Pawprint, infamouspat, Ruubbinnexx, H4M573R, Angelo Salese, Hammy]
This commit is contained in:
Angelo Salese 2023-05-21 22:17:46 +02:00 committed by GitHub
parent 9d39fbd6aa
commit a7425f83df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 1545 additions and 909 deletions

View File

@ -2793,8 +2793,18 @@ if (MACHINES["PCI"]~=null) then
MAME_DIR .. "src/devices/machine/i82439hx.h",
MAME_DIR .. "src/devices/machine/i82439tx.cpp",
MAME_DIR .. "src/devices/machine/i82439tx.h",
MAME_DIR .. "src/devices/machine/i82443bx_host.cpp",
MAME_DIR .. "src/devices/machine/i82443bx_host.h",
MAME_DIR .. "src/devices/machine/i82371sb.cpp",
MAME_DIR .. "src/devices/machine/i82371sb.h",
MAME_DIR .. "src/devices/machine/i82371eb_isa.cpp",
MAME_DIR .. "src/devices/machine/i82371eb_isa.h",
MAME_DIR .. "src/devices/machine/i82371eb_ide.cpp",
MAME_DIR .. "src/devices/machine/i82371eb_ide.h",
MAME_DIR .. "src/devices/machine/i82371eb_acpi.cpp",
MAME_DIR .. "src/devices/machine/i82371eb_acpi.h",
MAME_DIR .. "src/devices/machine/i82371eb_usb.cpp",
MAME_DIR .. "src/devices/machine/i82371eb_usb.h",
MAME_DIR .. "src/devices/machine/lpc.h",
MAME_DIR .. "src/devices/machine/lpc-acpi.cpp",
MAME_DIR .. "src/devices/machine/lpc-acpi.h",

View File

@ -14,10 +14,10 @@ SMSC FDC37C93x Plug and Play Compatible Ultra I/O Controller
#include "formats/naslite_dsk.h"
#include "formats/pc_dsk.h"
DEFINE_DEVICE_TYPE(FDC37C93X, fdc37c93x_device, "fdc37c93x", "SMSC FDC37C93X")
DEFINE_DEVICE_TYPE(FDC37C93X, fdc37c93x_device, "fdc37c93x", "SMSC FDC37C93X Super I/O")
fdc37c93x_device::fdc37c93x_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, FDC37C93X, tag, owner, clock)
fdc37c93x_device::fdc37c93x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, type, tag, owner, clock)
, device_isa16_card_interface(mconfig, *this)
, mode(OperatingMode::Run)
, config_key_step(0)
@ -71,6 +71,13 @@ fdc37c93x_device::fdc37c93x_device(const machine_config &mconfig, const char *ta
dreq_mapping[n] = -1;
}
fdc37c93x_device::fdc37c93x_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: fdc37c93x_device(mconfig, FDC37C93X, tag, owner, clock)
{
m_device_id = 0x02;
m_device_rev = 0x01;
}
/*
0 FDC:
60,61 03f0 +(0-7)
@ -902,10 +909,10 @@ uint16_t fdc37c93x_device::read_global_configuration_register(int index)
ret = logical_device;
break;
case 0x20:
ret = 2;
ret = m_device_id;
break;
case 0x21:
ret = 1;
ret = m_device_rev;
break;
}
logerror("Read global configuration register %02X = %02X\n", index, ret);
@ -991,3 +998,14 @@ void fdc37c93x_device::device_start()
void fdc37c93x_device::device_reset()
{
}
// 'M707 is mostly same except no IDE ports and extra power management regs
DEFINE_DEVICE_TYPE(FDC37M707, fdc37m707_device, "fdc37m707", "SMSC FDC37M707 Super I/O")
fdc37m707_device::fdc37m707_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: fdc37c93x_device(mconfig, FDC37M707, tag, owner, clock)
{
m_device_id = 0x42;
m_device_rev = 0x01;
}

View File

@ -99,6 +99,8 @@ public:
static void floppy_formats(format_registration &fr);
protected:
fdc37c93x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
@ -107,6 +109,9 @@ protected:
virtual void dack_w(int line, uint8_t data) override;
virtual void eop_w(int state) override;
u8 m_device_id = 0;
u8 m_device_rev = 0;
private:
// put your private members here
enum OperatingMode
@ -192,6 +197,15 @@ private:
uint16_t read_auxio_configuration_register(int index);
};
class fdc37m707_device : public fdc37c93x_device
{
public:
fdc37m707_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
~fdc37m707_device() {}
};
DECLARE_DEVICE_TYPE(FDC37C93X, fdc37c93x_device);
DECLARE_DEVICE_TYPE(FDC37M707, fdc37m707_device);
#endif // MAME_MACHINE_FDC37C93X_H

View File

@ -0,0 +1,194 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
/**************************************************************************************************
PIIX4E ACPI interface
TODO:
- PIIX4 / PIIX4M dispatches
**************************************************************************************************/
#include "emu.h"
#include "i82371eb_acpi.h"
#define LOG_IO (1U << 1) // log PCI register accesses
#define LOG_TODO (1U << 2) // log unimplemented registers
#define LOG_MAP (1U << 3) // log full remaps (verbose)
#define VERBOSE (LOG_GENERAL | LOG_IO | LOG_TODO | LOG_MAP)
//#define LOG_OUTPUT_FUNC osd_printf_warning
#include "logmacro.h"
#define LOGIO(...) LOGMASKED(LOG_IO, __VA_ARGS__)
#define LOGMAP(...) LOGMASKED(LOG_MAP, __VA_ARGS__)
#define LOGTODO(...) LOGMASKED(LOG_TODO, __VA_ARGS__)
DEFINE_DEVICE_TYPE(I82371EB_ACPI, i82371eb_acpi_device, "i82371eb_acpi", "Intel 82371EB PIIX4E Power Management and ACPI")
i82371eb_acpi_device::i82371eb_acpi_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: pci_device(mconfig, I82371EB_ACPI, tag, owner, clock)
, m_acpi(*this, "acpi")
, m_smbus(*this, "smbus")
{
// 0x068000 - Bridge devices, other bridge device
// rev 0x02 for PIIX4E A-0, rev 0x03 for PIIX4M
set_ids(0x80867113, 0x02, 0x068000, 0x00);
}
void i82371eb_acpi_device::device_add_mconfig(machine_config &config)
{
}
void i82371eb_acpi_device::config_map(address_map &map)
{
pci_device::config_map(map);
// TODO: has interrupt pin
map(0x10, 0xd7).unmaprw();
map(0x10, 0xd7).rw(FUNC(i82371eb_acpi_device::unmap_log_r), FUNC(i82371eb_acpi_device::unmap_log_w));
// I/O space
map(0x40, 0x43).rw(FUNC(i82371eb_acpi_device::pmba_r), FUNC(i82371eb_acpi_device::pmba_w));
map(0x5c, 0x5f).rw(FUNC(i82371eb_acpi_device::devresa_r), FUNC(i82371eb_acpi_device::devresa_w));
map(0x80, 0x80).rw(FUNC(i82371eb_acpi_device::pmregmisc_r), FUNC(i82371eb_acpi_device::pmregmisc_w));
// SMBus space
map(0x90, 0x93).rw(FUNC(i82371eb_acpi_device::smbba_r), FUNC(i82371eb_acpi_device::smbba_w));
map(0xd2, 0xd2).rw(FUNC(i82371eb_acpi_device::smbhstcfg_r), FUNC(i82371eb_acpi_device::smbhstcfg_w));
}
void i82371eb_acpi_device::io_map(address_map &map)
{
}
void i82371eb_acpi_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)
{
// printf("%08llx %08llx %08llx %04llx %04llx %04llx\n", memory_window_start, memory_window_end, memory_offset ,io_window_start, io_window_end, io_offset);
if (io_offset != 0)
throw emu_fatalerror("I82371EB_ACPI io_offset != 0 (%04llx)", io_offset);
//LOGMAP("PMIOSE %s\n", m_pmiose ? "Enable" : "Disable");
if (m_pmiose)
{
LOGMAP("- PMBA %04x-%04x\n", m_pmba, m_pmba + 0x3f);
// TODO: subset, should map up to 0x3f only (and current lpc-acpi don't)
m_acpi->map_device(memory_window_start, memory_window_end, 0, memory_space, io_window_start, m_pmba + 0x3f, m_pmba, io_space);
}
const bool iose = bool(BIT(command, 0));
LOGMAP("IOSE (SMBus) %s\n", m_pmiose ? "Enable" : "Disable");
// presume if SMB_HST_EN is zero will also remove SMBUS mapping
if (iose && BIT(m_smbus_host_config, 0))
{
LOGMAP("- SMBBA %04x-%04x (%08x %08x)\n", m_smbba, m_smbba + 0xf, io_window_start, io_window_end);
io_space->install_device(m_smbba, m_smbba | 0xf, *m_smbus, &smbus_device::map);
}
}
void i82371eb_acpi_device::device_start()
{
pci_device::device_start();
#if 0
memory_window_start = 0;
memory_window_end = 0xffffffff;
memory_offset = 0;
io_window_start = 0;
io_window_end = 0xffff;
io_offset = 0;
#endif
}
void i82371eb_acpi_device::device_reset()
{
pci_device::device_reset();
command = 0x0000;
status = 0x0280;
m_pmiose = false;
m_pmba = 0;
m_smbba = 0;
m_devresa = 0;
}
u8 i82371eb_acpi_device::pmregmisc_r()
{
return m_pmiose;
}
void i82371eb_acpi_device::pmregmisc_w(u8 data)
{
m_pmiose = bool(BIT(data, 0));
remap_cb();
}
u32 i82371eb_acpi_device::pmba_r()
{
// RTE bit 0 high (I/O space)
return m_pmba | 1;
}
void i82371eb_acpi_device::pmba_w(offs_t offset, u32 data, u32 mem_mask)
{
COMBINE_DATA(&m_pmba);
m_pmba &= 0xffc0;
remap_cb();
}
u32 i82371eb_acpi_device::devresa_r()
{
return m_devresa;
}
void i82371eb_acpi_device::devresa_w(offs_t offset, u32 data, u32 mem_mask)
{
COMBINE_DATA(&m_devresa);
LOGIO("devresa w %08x\n", m_devresa);
// remap_cb();
}
u32 i82371eb_acpi_device::smbba_r()
{
// RTE bit 0 high (I/O space)
return m_smbba | 1;
}
void i82371eb_acpi_device::smbba_w(offs_t offset, u32 data, u32 mem_mask)
{
COMBINE_DATA(&m_smbba);
m_smbba &= 0xfff0;
remap_cb();
}
u8 i82371eb_acpi_device::smbhstcfg_r()
{
return m_smbus_host_config;
}
void i82371eb_acpi_device::smbhstcfg_w(u8 data)
{
m_smbus_host_config = data;
remap_cb();
}
/*
* Debugging
*/
u8 i82371eb_acpi_device::unmap_log_r(offs_t offset)
{
LOGTODO("I82371EB_ACPI Unemulated [%02x] R\n", offset + 0x10);
return 0;
}
void i82371eb_acpi_device::unmap_log_w(offs_t offset, u8 data)
{
LOGTODO("I82371EB_ACPI Unemulated [%02x] %02x W\n", offset + 0x10, data);
}

View File

@ -0,0 +1,63 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
#ifndef MAME_MACHINE_I82371EB_ACPI_H
#define MAME_MACHINE_I82371EB_ACPI_H
#pragma once
#include "pci.h"
#include "lpc-acpi.h"
#include "pci-smbus.h"
class i82371eb_acpi_device : public pci_device
{
public:
i82371eb_acpi_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 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;
void io_map(address_map &map);
private:
required_device<lpc_acpi_device> m_acpi;
required_device<smbus_device> m_smbus;
u8 pmregmisc_r();
void pmregmisc_w(u8 data);
u8 smbhstcfg_r();
void smbhstcfg_w(u8 data);
u32 pmba_r();
void pmba_w(offs_t offset, u32 data, u32 mem_mask = ~0);
u32 devresa_r();
void devresa_w(offs_t offset, u32 data, u32 mem_mask = ~0);
u32 smbba_r();
void smbba_w(offs_t offset, u32 data, u32 mem_mask = ~0);
bool m_pmiose = false;
u32 m_pmba = 0;
u32 m_smbba = 0;
u8 m_smbus_host_config = 0;
u32 m_devresa = 0;
u8 unmap_log_r(offs_t offset);
void unmap_log_w(offs_t offset, u8 data);
};
DECLARE_DEVICE_TYPE(I82371EB_ACPI, i82371eb_acpi_device)
#endif

View File

@ -0,0 +1,37 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
/**************************************************************************************************
PIIX4E IDE interface
TODO:
- i82371ab PIIX4 / i82371mb PIIX4M dispatches
**************************************************************************************************/
#include "emu.h"
#include "i82371eb_ide.h"
#define LOG_IO (1U << 1) // log PCI register accesses
#define LOG_TODO (1U << 2) // log unimplemented registers
#define LOG_MAP (1U << 3) // log full remaps
#define VERBOSE (LOG_GENERAL | LOG_IO | LOG_TODO | LOG_MAP)
//#define LOG_OUTPUT_FUNC osd_printf_warning
#include "logmacro.h"
#define LOGIO(...) LOGMASKED(LOG_IO, __VA_ARGS__)
#define LOGMAP(...) LOGMASKED(LOG_MAP, __VA_ARGS__)
#define LOGTODO(...) LOGMASKED(LOG_TODO, __VA_ARGS__)
DEFINE_DEVICE_TYPE(I82371EB_IDE, i82371eb_ide_device, "i82371eb_ide", "Intel 82371EB PIIX4E PCI to ISA southbridge")
i82371eb_ide_device::i82371eb_ide_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: i82371sb_ide_device(mconfig, I82371EB_IDE, tag, owner, clock)
{
// 0x010180 - Mass storage device, IDE controller, bus master capable
// rev 0x00 PIIX4 A-0 / A-1
// rev 0x01 PIIX4 B-0 / PIIX4E A-0 / PIIX4M A-0
set_ids(0x80867111, 0x01, 0x010180, 0x00);
}

View File

@ -0,0 +1,26 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
#ifndef MAME_MACHINE_I82371EB_IDE_H
#define MAME_MACHINE_I82371EB_IDE_H
#pragma once
#include "machine/i82371sb.h"
class i82371eb_ide_device : public i82371sb_ide_device
{
public:
template <typename T>
i82371eb_ide_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&cpu_tag)
: i82371eb_ide_device(mconfig, tag, owner, clock)
{
set_cpu_tag(std::forward<T>(cpu_tag));
}
i82371eb_ide_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};
DECLARE_DEVICE_TYPE(I82371EB_IDE, i82371eb_ide_device)
#endif // MAME_MACHINE_I82371EB_IDE_H

View File

@ -0,0 +1,49 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
/**************************************************************************************************
PIIX4E ISA interface
TODO:
- i82371ab PIIX4 / i82371mb PIIX4M dispatches
- pinpoint actual differences wrt i82371sb (definitely EISA, then ...?)
**************************************************************************************************/
#include "emu.h"
#include "i82371eb_isa.h"
#define LOG_IO (1U << 1) // log PCI register accesses
#define LOG_TODO (1U << 2) // log unimplemented registers
#define LOG_MAP (1U << 3) // log full remaps
#define VERBOSE (LOG_GENERAL | LOG_IO | LOG_TODO | LOG_MAP)
//#define LOG_OUTPUT_FUNC osd_printf_warning
#include "logmacro.h"
#define LOGIO(...) LOGMASKED(LOG_IO, __VA_ARGS__)
#define LOGMAP(...) LOGMASKED(LOG_MAP, __VA_ARGS__)
#define LOGTODO(...) LOGMASKED(LOG_TODO, __VA_ARGS__)
DEFINE_DEVICE_TYPE(I82371EB_ISA, i82371eb_isa_device, "i82371eb_isa", "Intel 82371EB PIIX4E PCI to ISA/EIO southbridge")
i82371eb_isa_device::i82371eb_isa_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: i82371sb_isa_device(mconfig, I82371EB_ISA, tag, owner, clock)
{
// 0x060100 - Bridge device, PCI-to-ISA bridge
// TODO: above can change to 0x068000 if positive decode is used.
// rev 0x00 PIIX4 A-0 / A-1
// rev 0x01 PIIX4 B-0
// rev 0x02 for PIIX4E A-0 / PIIX4M A-0
set_ids(0x80867110, 0x02, 0x060100, 0x00);
}
void i82371eb_isa_device::config_map(address_map &map)
{
i82371sb_isa_device::config_map(map);
// map(0x90, 0x91) PDMACFG
// map(0xb0, 0xb0) GENCFG
}

View File

@ -0,0 +1,29 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
#ifndef MAME_MACHINE_I82371EB_ISA_H
#define MAME_MACHINE_I82371EB_ISA_H
#pragma once
#include "machine/i82371sb.h"
class i82371eb_isa_device : public i82371sb_isa_device
{
public:
template <typename T>
i82371eb_isa_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&cpu_tag)
: i82371eb_isa_device(mconfig, tag, owner, clock)
{
set_cpu_tag(std::forward<T>(cpu_tag));
}
i82371eb_isa_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
private:
virtual void config_map(address_map &map) override;
};
DECLARE_DEVICE_TYPE(I82371EB_ISA, i82371eb_isa_device)
#endif // MAME_MACHINE_I82371EB_ISA_H

View File

@ -0,0 +1,96 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
/**************************************************************************************************
PIIX4E USB interface
TODO:
- Actual USB ports;
**************************************************************************************************/
#include "emu.h"
#include "i82371eb_usb.h"
#define LOG_IO (1U << 1) // log PCI register accesses
#define LOG_TODO (1U << 2) // log unimplemented registers
#define LOG_MAP (1U << 3) // log full remaps
#define VERBOSE (LOG_GENERAL | LOG_IO | LOG_TODO | LOG_MAP)
//#define LOG_OUTPUT_FUNC osd_printf_warning
#include "logmacro.h"
#define LOGIO(...) LOGMASKED(LOG_IO, __VA_ARGS__)
#define LOGMAP(...) LOGMASKED(LOG_MAP, __VA_ARGS__)
#define LOGTODO(...) LOGMASKED(LOG_TODO, __VA_ARGS__)
DEFINE_DEVICE_TYPE(I82371EB_USB, i82371eb_usb_device, "i82371eb_usb", "Intel 82371EB PIIX4E USB Host Controller")
i82371eb_usb_device::i82371eb_usb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: pci_device(mconfig, I82371EB_USB, tag, owner, clock)
{
// 0x0c0300 - Serial Bus Controller, USB, UHCI Host
// rev PIIX4E A-0 / PIIX4M A-0 = 0x01
set_ids(0x80867112, 0x01, 0x0c0300, 0x00);
}
void i82371eb_usb_device::device_add_mconfig(machine_config &config)
{
}
void i82371eb_usb_device::config_map(address_map &map)
{
pci_device::config_map(map);
// 0x60 sbrnum - serial bus release number
// 0xc0-0xc1 legsup - Legacy Support Register
map(0x60, 0xff).rw(FUNC(i82371eb_usb_device::unmap_log_r), FUNC(i82371eb_usb_device::unmap_log_w));
}
void i82371eb_usb_device::io_map(address_map &map)
{
}
void i82371eb_usb_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, 0x03ff, *this, &i82371eb_usb_device::io_map);
}
void i82371eb_usb_device::device_start()
{
pci_device::device_start();
skip_map_regs(4);
add_map(32, M_IO, FUNC(i82371eb_usb_device::io_map));
// INTD#
intr_pin = 4;
}
void i82371eb_usb_device::device_reset()
{
pci_device::device_reset();
command = 0x0000;
status = 0x0280;
}
/*
* Debugging
*/
u8 i82371eb_usb_device::unmap_log_r(offs_t offset)
{
LOGTODO("I82371EB_USB Unemulated [%02x] R\n", offset + 0x60);
return 0;
}
void i82371eb_usb_device::unmap_log_w(offs_t offset, u8 data)
{
LOGTODO("I82371EB_USB Unemulated [%02x] %02x W\n", offset + 0x60, data);
}

View File

@ -0,0 +1,37 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
#ifndef MAME_MACHINE_I82371EB_USB_H
#define MAME_MACHINE_I82371EB_USB_H
#pragma once
#include "pci.h"
class i82371eb_usb_device : public pci_device
{
public:
i82371eb_usb_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 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;
void io_map(address_map &map);
private:
u8 unmap_log_r(offs_t offset);
void unmap_log_w(offs_t offset, u8 data);
};
DECLARE_DEVICE_TYPE(I82371EB_USB, i82371eb_usb_device)
#endif

View File

@ -6,7 +6,6 @@
#include "speaker.h"
DEFINE_DEVICE_TYPE(I82371SB_ISA, i82371sb_isa_device, "i82371sb_isa", "Intel 82371 southbridge ISA bridge")
void i82371sb_isa_device::config_map(address_map &map)
@ -55,14 +54,14 @@ void i82371sb_isa_device::internal_io_map(address_map &map)
void i82371sb_isa_device::device_add_mconfig(machine_config &config)
{
PIT8254(config, m_pit8254);
m_pit8254->set_clk<0>(4772720/4); // heartbeat IRQ
m_pit8254->set_clk<0>(4772720 / 4); // heartbeat IRQ
m_pit8254->out_handler<0>().set(FUNC(i82371sb_isa_device::at_pit8254_out0_changed));
m_pit8254->set_clk<1>(4772720/4); // DRAM refresh
m_pit8254->set_clk<1>(4772720 / 4); // DRAM refresh
m_pit8254->out_handler<1>().set(FUNC(i82371sb_isa_device::at_pit8254_out1_changed));
m_pit8254->set_clk<2>(4772720/4); // PIO port C pin 4, and speaker polling enough
m_pit8254->set_clk<2>(4772720 / 4); // PIO port C pin 4, and speaker polling enough
m_pit8254->out_handler<2>().set(FUNC(i82371sb_isa_device::at_pit8254_out2_changed));
AM9517A(config, m_dma8237_1, XTAL(14'318'181)/3);
AM9517A(config, m_dma8237_1, XTAL(14'318'181) / 3);
m_dma8237_1->out_hreq_callback().set(m_dma8237_2, FUNC(am9517a_device::dreq0_w));
m_dma8237_1->out_eop_callback().set(FUNC(i82371sb_isa_device::at_dma8237_out_eop));
m_dma8237_1->in_memr_callback().set(FUNC(i82371sb_isa_device::pc_dma_read_byte));
@ -80,7 +79,7 @@ void i82371sb_isa_device::device_add_mconfig(machine_config &config)
m_dma8237_1->out_dack_callback<2>().set(FUNC(i82371sb_isa_device::pc_dack2_w));
m_dma8237_1->out_dack_callback<3>().set(FUNC(i82371sb_isa_device::pc_dack3_w));
AM9517A(config, m_dma8237_2, XTAL(14'318'181)/3);
AM9517A(config, m_dma8237_2, XTAL(14'318'181) / 3);
m_dma8237_2->out_hreq_callback().set(FUNC(i82371sb_isa_device::pc_dma_hrq_changed));
m_dma8237_2->in_memr_callback().set(FUNC(i82371sb_isa_device::pc_dma_read_word));
m_dma8237_2->out_memw_callback().set(FUNC(i82371sb_isa_device::pc_dma_write_word));
@ -130,6 +129,12 @@ void i82371sb_isa_device::device_add_mconfig(machine_config &config)
m_isabus->iochck_callback().set(FUNC(i82371sb_isa_device::iochck_w));
}
i82371sb_isa_device::i82371sb_isa_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: i82371sb_isa_device(mconfig, I82371SB_ISA, tag, owner, clock)
{
set_ids(0x80867000, 0x03, 0x060100, 0x00000000);
}
void i82371sb_isa_device::device_config_complete()
{
auto isabus = m_isabus.finder_target();
@ -139,23 +144,9 @@ void i82371sb_isa_device::device_config_complete()
pci_device::device_config_complete();
}
i82371sb_isa_device::i82371sb_isa_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
pci_device(mconfig, I82371SB_ISA, 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"),
m_at_spkrdata(0), m_pit_out2(0), m_dma_channel(0), m_cur_eop(false), m_dma_high_byte(0), m_eisa_irq_mode(0), m_at_speaker(0), m_refresh(false), m_channel_check(0), m_nmi_enabled(0)
i82371sb_isa_device::i82371sb_isa_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: pci_device(mconfig, type, 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"), m_at_spkrdata(0), m_pit_out2(0), m_dma_channel(0), m_cur_eop(false), m_dma_high_byte(0), m_eisa_irq_mode(0), m_at_speaker(0), m_refresh(false), m_channel_check(0), m_nmi_enabled(0)
{
set_ids(0x80867000, 0x03, 0x060100, 0x00000000);
}
void i82371sb_isa_device::device_start()
@ -434,7 +425,7 @@ void i82371sb_isa_device::map_extra(uint64_t memory_window_start, uint64_t memor
{
// assume that map_extra of the southbridge is called before the one of the northbridge
m_isabus->remap(AS_PROGRAM, 0, 1 << 24);
map_bios(memory_space, 0xfffc0000, 0xffffffff);
map_bios(memory_space, 0xffffffff - m_region->bytes() + 1, 0xffffffff);
map_bios(memory_space, 0x000e0000, 0x000fffff);
m_isabus->remap(AS_IO, 0, 0xffff);
io_space->install_device(0, 0xffff, *this, &i82371sb_isa_device::internal_io_map);
@ -525,11 +516,10 @@ void i82371sb_isa_device::map_extra(uint64_t memory_window_start, uint64_t memor
#endif
}
// Southbridge
uint8_t i82371sb_isa_device::get_slave_ack(offs_t offset)
{
if (offset==2) // IRQ = 2
if (offset == 2) // IRQ = 2
return m_pic8259_slave->acknowledge();
return 0x00;
@ -541,21 +531,19 @@ void i82371sb_isa_device::at_speaker_set_spkrdata(uint8_t data)
m_speaker->level_w(m_at_spkrdata & m_pit_out2);
}
WRITE_LINE_MEMBER( i82371sb_isa_device::at_pit8254_out0_changed )
WRITE_LINE_MEMBER(i82371sb_isa_device::at_pit8254_out0_changed)
{
if (m_pic8259_master)
m_pic8259_master->ir0_w(state);
}
WRITE_LINE_MEMBER( i82371sb_isa_device::at_pit8254_out1_changed )
WRITE_LINE_MEMBER(i82371sb_isa_device::at_pit8254_out1_changed)
{
if(state)
if (state)
m_refresh = !m_refresh;
}
WRITE_LINE_MEMBER( i82371sb_isa_device::at_pit8254_out2_changed )
WRITE_LINE_MEMBER(i82371sb_isa_device::at_pit8254_out2_changed)
{
m_pit_out2 = state ? 1 : 0;
m_speaker->level_w(m_at_spkrdata & m_pit_out2);
@ -565,7 +553,7 @@ uint8_t i82371sb_isa_device::at_page8_r(offs_t offset)
{
uint8_t data = m_at_pages[offset % 0x10];
switch(offset % 8)
switch (offset % 8)
{
case 1:
data = m_dma_offset[BIT(offset, 3)][2];
@ -583,12 +571,11 @@ uint8_t i82371sb_isa_device::at_page8_r(offs_t offset)
return data;
}
void i82371sb_isa_device::at_page8_w(offs_t offset, uint8_t data)
{
m_at_pages[offset % 0x10] = data;
switch(offset % 8)
switch (offset % 8)
{
case 0:
m_boot_state_hook((offs_t)0, data);
@ -608,46 +595,43 @@ void i82371sb_isa_device::at_page8_w(offs_t offset, uint8_t data)
}
}
WRITE_LINE_MEMBER( i82371sb_isa_device::pc_dma_hrq_changed )
WRITE_LINE_MEMBER(i82371sb_isa_device::pc_dma_hrq_changed)
{
m_maincpu->set_input_line(INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE);
/* Assert HLDA */
m_dma8237_2->hack_w( state );
m_dma8237_2->hack_w(state);
}
uint8_t i82371sb_isa_device::pc_dma_read_byte(offs_t offset)
{
address_space& prog_space = m_maincpu->space(AS_PROGRAM); // get the right address space
if(m_dma_channel == -1)
address_space &prog_space = m_maincpu->space(AS_PROGRAM); // get the right address space
if (m_dma_channel == -1)
return 0xff;
uint8_t result;
offs_t page_offset = ((offs_t) m_dma_offset[0][m_dma_channel]) << 16;
offs_t page_offset = ((offs_t)m_dma_offset[0][m_dma_channel]) << 16;
result = prog_space.read_byte(page_offset + offset);
return result;
}
void i82371sb_isa_device::pc_dma_write_byte(offs_t offset, uint8_t data)
{
address_space& prog_space = m_maincpu->space(AS_PROGRAM); // get the right address space
if(m_dma_channel == -1)
address_space &prog_space = m_maincpu->space(AS_PROGRAM); // get the right address space
if (m_dma_channel == -1)
return;
offs_t page_offset = ((offs_t) m_dma_offset[0][m_dma_channel]) << 16;
offs_t page_offset = ((offs_t)m_dma_offset[0][m_dma_channel]) << 16;
prog_space.write_byte(page_offset + offset, data);
}
uint8_t i82371sb_isa_device::pc_dma_read_word(offs_t offset)
{
address_space& prog_space = m_maincpu->space(AS_PROGRAM); // get the right address space
if(m_dma_channel == -1)
address_space &prog_space = m_maincpu->space(AS_PROGRAM); // get the right address space
if (m_dma_channel == -1)
return 0xff;
uint16_t result;
offs_t page_offset = ((offs_t) m_dma_offset[1][m_dma_channel & 3]) << 16;
offs_t page_offset = ((offs_t)m_dma_offset[1][m_dma_channel & 3]) << 16;
result = prog_space.read_word((page_offset & 0xfe0000) | (offset << 1));
m_dma_high_byte = result & 0xFF00;
@ -655,18 +639,16 @@ uint8_t i82371sb_isa_device::pc_dma_read_word(offs_t offset)
return result & 0xFF;
}
void i82371sb_isa_device::pc_dma_write_word(offs_t offset, uint8_t data)
{
address_space& prog_space = m_maincpu->space(AS_PROGRAM); // get the right address space
if(m_dma_channel == -1)
address_space &prog_space = m_maincpu->space(AS_PROGRAM); // get the right address space
if (m_dma_channel == -1)
return;
offs_t page_offset = ((offs_t) m_dma_offset[1][m_dma_channel & 3]) << 16;
offs_t page_offset = ((offs_t)m_dma_offset[1][m_dma_channel & 3]) << 16;
prog_space.write_word((page_offset & 0xfe0000) | (offset << 1), m_dma_high_byte | data);
}
uint8_t i82371sb_isa_device::pc_dma8237_0_dack_r() { return m_isabus->dack_r(0); }
uint8_t i82371sb_isa_device::pc_dma8237_1_dack_r() { return m_isabus->dack_r(1); }
uint8_t i82371sb_isa_device::pc_dma8237_2_dack_r() { return m_isabus->dack_r(2); }
@ -675,7 +657,6 @@ uint8_t i82371sb_isa_device::pc_dma8237_5_dack_r() { return m_isabus->dack_r(5);
uint8_t i82371sb_isa_device::pc_dma8237_6_dack_r() { return m_isabus->dack_r(6); }
uint8_t i82371sb_isa_device::pc_dma8237_7_dack_r() { return m_isabus->dack_r(7); }
void i82371sb_isa_device::pc_dma8237_0_dack_w(uint8_t data) { m_isabus->dack_w(0, data); }
void i82371sb_isa_device::pc_dma8237_1_dack_w(uint8_t data) { m_isabus->dack_w(1, data); }
void i82371sb_isa_device::pc_dma8237_2_dack_w(uint8_t data) { m_isabus->dack_w(2, data); }
@ -684,37 +665,39 @@ void i82371sb_isa_device::pc_dma8237_5_dack_w(uint8_t data) { m_isabus->dack_w(5
void i82371sb_isa_device::pc_dma8237_6_dack_w(uint8_t data) { m_isabus->dack_w(6, data); }
void i82371sb_isa_device::pc_dma8237_7_dack_w(uint8_t data) { m_isabus->dack_w(7, data); }
WRITE_LINE_MEMBER( i82371sb_isa_device::at_dma8237_out_eop )
WRITE_LINE_MEMBER(i82371sb_isa_device::at_dma8237_out_eop)
{
m_cur_eop = state == ASSERT_LINE;
if(m_dma_channel != -1)
m_isabus->eop_w(m_dma_channel, m_cur_eop ? ASSERT_LINE : CLEAR_LINE );
if (m_dma_channel != -1)
m_isabus->eop_w(m_dma_channel, m_cur_eop ? ASSERT_LINE : CLEAR_LINE);
}
void i82371sb_isa_device::pc_select_dma_channel(int channel, bool state)
{
m_isabus->dack_line_w(channel, state);
if(!state) {
if (!state)
{
m_dma_channel = channel;
if(m_cur_eop)
m_isabus->eop_w(channel, ASSERT_LINE );
} else if(m_dma_channel == channel) {
if (m_cur_eop)
m_isabus->eop_w(channel, ASSERT_LINE);
}
else if (m_dma_channel == channel)
{
m_dma_channel = -1;
if(m_cur_eop)
m_isabus->eop_w(channel, CLEAR_LINE );
if (m_cur_eop)
m_isabus->eop_w(channel, CLEAR_LINE);
}
}
WRITE_LINE_MEMBER( i82371sb_isa_device::pc_dack0_w ) { pc_select_dma_channel(0, state); }
WRITE_LINE_MEMBER( i82371sb_isa_device::pc_dack1_w ) { pc_select_dma_channel(1, state); }
WRITE_LINE_MEMBER( i82371sb_isa_device::pc_dack2_w ) { pc_select_dma_channel(2, state); }
WRITE_LINE_MEMBER( i82371sb_isa_device::pc_dack3_w ) { pc_select_dma_channel(3, state); }
WRITE_LINE_MEMBER( i82371sb_isa_device::pc_dack4_w ) { m_dma8237_1->hack_w( state ? 0 : 1); } // it's inverted
WRITE_LINE_MEMBER( i82371sb_isa_device::pc_dack5_w ) { pc_select_dma_channel(5, state); }
WRITE_LINE_MEMBER( i82371sb_isa_device::pc_dack6_w ) { pc_select_dma_channel(6, state); }
WRITE_LINE_MEMBER( i82371sb_isa_device::pc_dack7_w ) { pc_select_dma_channel(7, state); }
WRITE_LINE_MEMBER(i82371sb_isa_device::pc_dack0_w) { pc_select_dma_channel(0, state); }
WRITE_LINE_MEMBER(i82371sb_isa_device::pc_dack1_w) { pc_select_dma_channel(1, state); }
WRITE_LINE_MEMBER(i82371sb_isa_device::pc_dack2_w) { pc_select_dma_channel(2, state); }
WRITE_LINE_MEMBER(i82371sb_isa_device::pc_dack3_w) { pc_select_dma_channel(3, state); }
WRITE_LINE_MEMBER(i82371sb_isa_device::pc_dack4_w) { m_dma8237_1->hack_w(state ? 0 : 1); } // it's inverted
WRITE_LINE_MEMBER(i82371sb_isa_device::pc_dack5_w) { pc_select_dma_channel(5, state); }
WRITE_LINE_MEMBER(i82371sb_isa_device::pc_dack6_w) { pc_select_dma_channel(6, state); }
WRITE_LINE_MEMBER(i82371sb_isa_device::pc_dack7_w) { pc_select_dma_channel(7, state); }
void i82371sb_isa_device::redirect_irq(int irq, int state)
{
@ -762,7 +745,7 @@ void i82371sb_isa_device::redirect_irq(int irq, int state)
}
}
WRITE_LINE_MEMBER( i82371sb_isa_device::pc_pirqa_w)
WRITE_LINE_MEMBER(i82371sb_isa_device::pc_pirqa_w)
{
int irq = pirqrc[0] & 15;
@ -771,7 +754,7 @@ WRITE_LINE_MEMBER( i82371sb_isa_device::pc_pirqa_w)
redirect_irq(irq, state);
}
WRITE_LINE_MEMBER( i82371sb_isa_device::pc_pirqb_w )
WRITE_LINE_MEMBER(i82371sb_isa_device::pc_pirqb_w)
{
int irq = pirqrc[1] & 15;
@ -780,7 +763,7 @@ WRITE_LINE_MEMBER( i82371sb_isa_device::pc_pirqb_w )
redirect_irq(irq, state);
}
WRITE_LINE_MEMBER( i82371sb_isa_device::pc_pirqc_w )
WRITE_LINE_MEMBER(i82371sb_isa_device::pc_pirqc_w)
{
int irq = pirqrc[2] & 15;
@ -789,7 +772,7 @@ WRITE_LINE_MEMBER( i82371sb_isa_device::pc_pirqc_w )
redirect_irq(irq, state);
}
WRITE_LINE_MEMBER( i82371sb_isa_device::pc_pirqd_w )
WRITE_LINE_MEMBER(i82371sb_isa_device::pc_pirqd_w)
{
int irq = pirqrc[3] & 15;
@ -798,7 +781,7 @@ WRITE_LINE_MEMBER( i82371sb_isa_device::pc_pirqd_w )
redirect_irq(irq, state);
}
WRITE_LINE_MEMBER( i82371sb_isa_device::pc_mirq0_w )
WRITE_LINE_MEMBER(i82371sb_isa_device::pc_mirq0_w)
{
int irq = mbirq0 & 15;
@ -807,7 +790,7 @@ WRITE_LINE_MEMBER( i82371sb_isa_device::pc_mirq0_w )
redirect_irq(irq, state);
}
WRITE_LINE_MEMBER( i82371sb_isa_device::pc_mirq1_w )
WRITE_LINE_MEMBER(i82371sb_isa_device::pc_mirq1_w)
{
int irq = mbirq1 & 15;
@ -816,7 +799,7 @@ WRITE_LINE_MEMBER( i82371sb_isa_device::pc_mirq1_w )
redirect_irq(irq, state);
}
WRITE_LINE_MEMBER( i82371sb_isa_device::pc_ferr_w )
WRITE_LINE_MEMBER(i82371sb_isa_device::pc_ferr_w)
{
if (!(xbcs & 32))
return;
@ -827,20 +810,19 @@ WRITE_LINE_MEMBER(i82371sb_isa_device::pc_extsmi_w)
{
}
WRITE_LINE_MEMBER( i82371sb_isa_device::pc_irq1_w ) { m_pic8259_master->ir1_w(state); }
WRITE_LINE_MEMBER( i82371sb_isa_device::pc_irq3_w ) { m_pic8259_master->ir3_w(state); }
WRITE_LINE_MEMBER( i82371sb_isa_device::pc_irq4_w ) { m_pic8259_master->ir4_w(state); }
WRITE_LINE_MEMBER( i82371sb_isa_device::pc_irq5_w ) { m_pic8259_master->ir5_w(state); }
WRITE_LINE_MEMBER( i82371sb_isa_device::pc_irq6_w ) { m_pic8259_master->ir6_w(state); }
WRITE_LINE_MEMBER( i82371sb_isa_device::pc_irq7_w ) { m_pic8259_master->ir7_w(state); }
WRITE_LINE_MEMBER( i82371sb_isa_device::pc_irq8n_w ) { m_pic8259_slave->ir0_w(state); }
WRITE_LINE_MEMBER( i82371sb_isa_device::pc_irq9_w ) { m_pic8259_slave->ir1_w(state); }
WRITE_LINE_MEMBER( i82371sb_isa_device::pc_irq10_w ) { m_pic8259_slave->ir2_w(state); }
WRITE_LINE_MEMBER( i82371sb_isa_device::pc_irq11_w ) { m_pic8259_slave->ir3_w(state); }
WRITE_LINE_MEMBER( i82371sb_isa_device::pc_irq12m_w ) { m_pic8259_slave->ir4_w(state); }
WRITE_LINE_MEMBER( i82371sb_isa_device::pc_irq14_w ) { m_pic8259_slave->ir6_w(state); }
WRITE_LINE_MEMBER( i82371sb_isa_device::pc_irq15_w ) { m_pic8259_slave->ir7_w(state); }
WRITE_LINE_MEMBER(i82371sb_isa_device::pc_irq1_w) { m_pic8259_master->ir1_w(state); }
WRITE_LINE_MEMBER(i82371sb_isa_device::pc_irq3_w) { m_pic8259_master->ir3_w(state); }
WRITE_LINE_MEMBER(i82371sb_isa_device::pc_irq4_w) { m_pic8259_master->ir4_w(state); }
WRITE_LINE_MEMBER(i82371sb_isa_device::pc_irq5_w) { m_pic8259_master->ir5_w(state); }
WRITE_LINE_MEMBER(i82371sb_isa_device::pc_irq6_w) { m_pic8259_master->ir6_w(state); }
WRITE_LINE_MEMBER(i82371sb_isa_device::pc_irq7_w) { m_pic8259_master->ir7_w(state); }
WRITE_LINE_MEMBER(i82371sb_isa_device::pc_irq8n_w) { m_pic8259_slave->ir0_w(state); }
WRITE_LINE_MEMBER(i82371sb_isa_device::pc_irq9_w) { m_pic8259_slave->ir1_w(state); }
WRITE_LINE_MEMBER(i82371sb_isa_device::pc_irq10_w) { m_pic8259_slave->ir2_w(state); }
WRITE_LINE_MEMBER(i82371sb_isa_device::pc_irq11_w) { m_pic8259_slave->ir3_w(state); }
WRITE_LINE_MEMBER(i82371sb_isa_device::pc_irq12m_w) { m_pic8259_slave->ir4_w(state); }
WRITE_LINE_MEMBER(i82371sb_isa_device::pc_irq14_w) { m_pic8259_slave->ir6_w(state); }
WRITE_LINE_MEMBER(i82371sb_isa_device::pc_irq15_w) { m_pic8259_slave->ir7_w(state); }
uint8_t i82371sb_isa_device::at_portb_r()
{
@ -849,7 +831,7 @@ uint8_t i82371sb_isa_device::at_portb_r()
data &= ~0xd0; /* AT BIOS don't likes this being set */
/* 0x10 is the dram refresh line bit on the 5170, just a timer here, 15.085us. */
data |= m_refresh ? 0x10 : 0;
if (m_pit_out2)
if (m_pit_out2)
data |= 0x20;
else
data &= ~0x20; /* ps2m30 wants this */
@ -861,13 +843,13 @@ void i82371sb_isa_device::at_portb_w(uint8_t data)
{
m_at_speaker = data;
m_pit8254->write_gate2(BIT(data, 0));
at_speaker_set_spkrdata( BIT(data, 1));
at_speaker_set_spkrdata(BIT(data, 1));
m_channel_check = BIT(data, 3);
if (m_channel_check)
m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
}
WRITE_LINE_MEMBER( i82371sb_isa_device::iochck_w )
WRITE_LINE_MEMBER(i82371sb_isa_device::iochck_w)
{
if (!state && !m_channel_check && m_nmi_enabled)
m_maincpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE);
@ -988,8 +970,8 @@ void i82371sb_ide_device::device_config_complete()
pci_device::device_config_complete();
}
i82371sb_ide_device::i82371sb_ide_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: pci_device(mconfig, I82371SB_IDE, tag, owner, clock)
i82371sb_ide_device::i82371sb_ide_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: pci_device(mconfig, type, tag, owner, clock)
, latency_timer(0)
, bmiba(1)
, idetim_primary(0)
@ -1000,6 +982,11 @@ i82371sb_ide_device::i82371sb_ide_device(const machine_config &mconfig, const ch
, m_maincpu(*this, finder_base::DUMMY_TAG)
, m_ide1(*this, "ide1")
, m_ide2(*this, "ide2")
{
}
i82371sb_ide_device::i82371sb_ide_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: i82371sb_ide_device(mconfig, I82371SB_IDE, tag, owner, clock)
{
set_ids(0x80867010, 0, 0x010180, 0x00000000);
}
@ -1023,7 +1010,7 @@ void i82371sb_ide_device::reset_all_mappings()
}
void i82371sb_ide_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)
uint64_t io_window_start, uint64_t io_window_end, uint64_t io_offset, address_space *io_space)
{
io_space->install_device(0, 0x3ff, *this, &i82371sb_ide_device::internal_io_map);
if (command & 1)

View File

@ -23,8 +23,8 @@
#include "machine/am9517a.h"
class i82371sb_isa_device : public pci_device {
class i82371sb_isa_device : public pci_device
{
public:
template <typename T>
i82371sb_isa_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&cpu_tag)
@ -67,7 +67,9 @@ public:
DECLARE_WRITE_LINE_MEMBER(pc_irq15_w);
protected:
virtual void device_add_mconfig(machine_config &config) override;
i82371sb_isa_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
virtual void device_add_mconfig(machine_config & config) override;
virtual void device_config_complete() override;
virtual void device_start() override;
virtual void device_reset() override;
@ -111,7 +113,7 @@ private:
uint8_t pc_dma_read_byte(offs_t offset);
void pc_dma_write_byte(offs_t offset, uint8_t data);
uint8_t pc_dma_read_word(offs_t offset);
void pc_dma_write_word(offs_t offset,uint8_t data);
void pc_dma_write_word(offs_t offset, uint8_t data);
uint8_t get_slave_ack(offs_t offset);
void internal_io_map(address_map &map);
@ -186,7 +188,7 @@ private:
void map_bios(address_space *memory_space, uint32_t start, uint32_t end);
//southbridge
// southbridge
required_device<cpu_device> m_maincpu;
required_device<pic8259_device> m_pic8259_master;
required_device<pic8259_device> m_pic8259_slave;
@ -217,8 +219,8 @@ private:
DECLARE_DEVICE_TYPE(I82371SB_ISA, i82371sb_isa_device)
class i82371sb_ide_device : public pci_device {
class i82371sb_ide_device : public pci_device
{
public:
template <typename T>
i82371sb_ide_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&cpu_tag)
@ -236,6 +238,8 @@ public:
void set_cpu_tag(T &&tag) { m_maincpu.set_tag(std::forward<T>(tag)); }
protected:
i82371sb_ide_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
virtual void device_add_mconfig(machine_config &config) override;
virtual void device_config_complete() override;
virtual void device_start() override;
@ -243,7 +247,7 @@ protected:
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;
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;

View File

@ -28,12 +28,18 @@ void i82439hx_host_device::config_map(address_map &map)
map(0x92, 0x92).r(FUNC(i82439hx_host_device::errsyn_r));
}
i82439hx_host_device::i82439hx_host_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: pci_host_device(mconfig, I82439HX, tag, owner, clock)
i82439hx_host_device::i82439hx_host_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: pci_host_device(mconfig, type, tag, owner, clock)
, cpu(*this, finder_base::DUMMY_TAG)
{
}
i82439hx_host_device::i82439hx_host_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: i82439hx_host_device(mconfig, I82439HX, tag, owner, clock)
{
set_ids_host(0x80861250, 0x03, 0x00000000);
}
void i82439hx_host_device::set_ram_size(int _ram_size)
{
ram_size = _ram_size;
@ -86,18 +92,27 @@ void i82439hx_host_device::device_reset()
smiact_n = 1;
}
std::tuple<bool, bool> i82439hx_host_device::read_memory_holes()
{
const bool lower_hole = (dramc & 0xc0) == 0x40;
const bool upper_hole = (dramc & 0xc0) != 0x80;
return std::make_tuple(lower_hole, upper_hole);
}
void i82439hx_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);
auto [memory_hole_lower, memory_hole_upper] = read_memory_holes();
// memory hole at 512-640 kbytes
if((dramc & 0xc0) == 0x40)
if(memory_hole_lower)
memory_space->install_ram (0x00000000, 0x0007ffff, &ram[0x00000000/4]);
else
memory_space->install_ram (0x00000000, 0x0009ffff, &ram[0x00000000/4]);
// assume that map_extra of the northbridge is called after the video card has mepped its memory here
// assume that map_extra of the northbridge is called after the video card has mapped its memory here
if (smram & 0x08)
{
if (smiact_n == 0)
@ -163,7 +178,7 @@ void i82439hx_host_device::map_extra(uint64_t memory_window_start, uint64_t memo
memory_space->install_ram (0x00100000, 0x00efffff, &ram[0x00100000/4]);
// memory hole at 15-16 mbytes
if((dramc & 0xc0) != 0x80)
if(memory_hole_upper)
memory_space->install_ram (0x00f00000, 0x00ffffff, &ram[0x00f00000/4]);
memory_space->install_ram (0x01000000, ram_size-1, &ram[0x01000000/4]);

View File

@ -15,7 +15,6 @@ public:
i82439hx_host_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&cpu_tag, int ram_size)
: i82439hx_host_device(mconfig, tag, owner, clock)
{
set_ids_host(0x80861250, 0x03, 0x00000000);
set_cpu_tag(std::forward<T>(cpu_tag));
set_ram_size(ram_size);
}
@ -27,6 +26,8 @@ public:
DECLARE_WRITE_LINE_MEMBER(smi_act_w);
protected:
i82439hx_host_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
virtual void device_start() override;
virtual void device_reset() override;
@ -37,6 +38,8 @@ protected:
virtual void config_map(address_map &map) override;
virtual std::tuple<bool, bool> read_memory_holes();
private:
int ram_size;
required_device<device_memory_interface> cpu;

View File

@ -0,0 +1,167 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
/**************************************************************************************************
Intel 440BX 82443BX Host section
TODO:
- better subclassing leap, we currently use i82339hx base for convenience
**************************************************************************************************/
#include "emu.h"
#include "i82443bx_host.h"
#define LOG_IO (1U << 1) // log PCI register accesses
#define LOG_TODO (1U << 2) // log unimplemented registers
#define LOG_MAP (1U << 3) // log full remaps
#define VERBOSE (LOG_GENERAL | LOG_IO | LOG_TODO | LOG_MAP)
#define LOG_OUTPUT_FUNC osd_printf_warning
#include "logmacro.h"
#define LOGIO(...) LOGMASKED(LOG_IO, __VA_ARGS__)
#define LOGMAP(...) LOGMASKED(LOG_MAP, __VA_ARGS__)
#define LOGTODO(...) LOGMASKED(LOG_TODO, __VA_ARGS__)
DEFINE_DEVICE_TYPE(I82443BX_HOST, i82443bx_host_device, "i82443bx_host", "Intel 82443BX PAC Host to PCI northbridge")
i82443bx_host_device::i82443bx_host_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: i82439hx_host_device(mconfig, I82443BX_HOST, tag, owner, clock)
{
// TODO: Device ID (DID) is 0x7192 when AGP_DIS is '1'
// rev 0x02 82443BX B-1
set_ids_host(0x80867190, 0x02, 0x00000000);
}
void i82443bx_host_device::config_map(address_map &map)
{
i82439hx_host_device::config_map(map);
// override first BAR slot for gfx window base address
map(0x10, 0x13).rw(FUNC(pci_device::address_base_r), FUNC(pci_device::address_base_w));
map(0x34, 0x34).r(FUNC(i82443bx_host_device::capptr_r));
// map(0x50, 0x53).lr32(NAME([this] () { return machine().rand(); }));
// TODO: no DRT, moved as DRTC / DWTC in dword format to $e0/$e8
map(0x68, 0x68).rw(FUNC(i82443bx_host_device::fdhc_r), FUNC(i82443bx_host_device::fdhc_w));
// TODO: midqslvr.cpp r/ws the AGPCTRL register but don't seem to match what's in datasheet
// I also haven't yet enabled CAPPTR lolwut?
//map(0xb0, 0xb3)
map(0xd0, 0xd7).rw(FUNC(i82443bx_host_device::bspad_r), FUNC(i82443bx_host_device::bspad_w));
}
void i82443bx_host_device::apbase_map(address_map &map)
{
// ...
}
void i82443bx_host_device::device_start()
{
i82439hx_host_device::device_start();
// TODO: size
add_map(8*1024*1024, M_MEM, FUNC(i82443bx_host_device::apbase_map));
save_item(NAME(m_fdhc));
save_pointer(NAME(m_bspad), 8);
}
void i82443bx_host_device::device_reset()
{
i82439hx_host_device::device_reset();
m_fdhc = 0;
for (int i = 0; i < 8; i++)
m_bspad[i] = 0;
}
u8 i82443bx_host_device::capptr_r()
{
return 0xa0;
}
// Register is different wrt i82439hx
std::tuple<bool, bool> i82443bx_host_device::read_memory_holes()
{
const bool lower_hole = (m_fdhc & 0xc0) == 0x40;
// TODO: 11 is "reserved"
const bool upper_hole = (m_fdhc & 0xc0) != 0x80;
return std::make_tuple(lower_hole, upper_hole);
}
u8 i82443bx_host_device::fdhc_r()
{
return m_fdhc;
}
void i82443bx_host_device::fdhc_w(u8 data)
{
m_fdhc = data;
LOGIO("FDHC = %02x\n", data);
remap_cb();
}
/*
* BSPAD - BIOS Scratch Pad Register
* 8 bytes of pseudo-RAM
*/
u8 i82443bx_host_device::bspad_r(offs_t offset)
{
LOGIO("BSPAD[%d] R\n", offset);
return m_bspad[offset];
}
void i82443bx_host_device::bspad_w(offs_t offset, u8 data)
{
LOGIO("BSPAD[%d] = %02x\n", offset, data);
m_bspad[offset] = data;
}
/*****************************
*
* Virtual PCI-to-PCI bridge implementation
*
****************************/
DEFINE_DEVICE_TYPE(I82443BX_BRIDGE, i82443bx_bridge_device, "i82443bx_bridge", "Intel 82443BX Virtual PCI-to-PCI bridge")
i82443bx_bridge_device::i82443bx_bridge_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: pci_bridge_device(mconfig, I82443BX_BRIDGE, tag, owner, clock)
// , m_vga(*this, finder_base::DUMMY_TAG)
{
set_ids_bridge(0x80867191, 0x00);
}
void i82443bx_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
)
{
if (BIT(bridge_control, 3))
{
//memory_space->install_device(0, 0xfffff, *m_vga, &sis630_gui_device::legacy_memory_map);
//io_space->install_device(0, 0x0fff, *m_vga, &sis630_gui_device::legacy_io_map);
}
}
void i82443bx_bridge_device::bridge_control_w(offs_t offset, uint16_t data, uint16_t mem_mask)
{
pci_bridge_device::bridge_control_w(offset, data, mem_mask);
LOGMAP("- %s VGA control\n", bridge_control & 8 ? "Enable" : "Disable");
remap_cb();
}
void i82443bx_bridge_device::device_start()
{
pci_bridge_device::device_start();
}
void i82443bx_bridge_device::device_reset()
{
pci_bridge_device::device_reset();
}

View File

@ -0,0 +1,78 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
#ifndef MAME_MACHINE_I82443BX_HOST_H
#define MAME_MACHINE_I82443BX_HOST_H
#pragma once
#include "pci.h"
#include "machine/i82439hx.h"
class i82443bx_host_device : public i82439hx_host_device {
public:
template <typename T>
i82443bx_host_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&cpu_tag, int ram_size)
: i82443bx_host_device(mconfig, tag, owner, clock)
{
set_cpu_tag(std::forward<T>(cpu_tag));
set_ram_size(ram_size);
}
i82443bx_host_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
virtual void config_map(address_map &map) override;
virtual void device_start() override;
virtual void device_reset() override;
virtual void apbase_map(address_map &map);
virtual u8 capptr_r() override;
private:
virtual std::tuple<bool, bool> read_memory_holes() override;
u8 m_fdhc = 0;
u8 m_bspad[8]{};
u8 fdhc_r();
void fdhc_w(u8 data);
u8 bspad_r(offs_t offset);
void bspad_w(offs_t offset, u8 data);
};
class i82443bx_bridge_device : public pci_bridge_device
{
public:
/*template <typename T> sis630_bridge_device(
const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock,
T &&gui_tag
) : sis630_bridge_device(mconfig, tag, owner, clock)
{
// either 0001 or 6001 as device ID
set_ids_bridge(0x10396001, 0x00);
//set_multifunction_device(true);
//m_vga.set_tag(std::forward<T>(gui_tag));
}*/
i82443bx_bridge_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 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;
private:
//required_device<sis630_gui_device> m_vga;
virtual void bridge_control_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0) override;
};
DECLARE_DEVICE_TYPE(I82443BX_HOST, i82443bx_host_device)
DECLARE_DEVICE_TYPE(I82443BX_BRIDGE, i82443bx_bridge_device)
#endif // MAME_MACHINE_I82443BX_HOST_H

View File

@ -14,12 +14,13 @@ public:
}
smbus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
void map(address_map &map);
protected:
virtual void device_start() override;
virtual void device_reset() override;
private:
void map(address_map &map);
uint8_t hst_sts_r();
void hst_sts_w(uint8_t data);

View File

@ -134,8 +134,6 @@ private:
required_device<sis630_gui_device> m_vga;
virtual void bridge_control_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0) override;
};
DECLARE_DEVICE_TYPE(SIS630_BRIDGE, sis630_bridge_device)

View File

@ -31733,7 +31733,9 @@ wmstopb // (c) 1999 WMS - Top Banana (Russian)
yukongld // (c) 2000 WMS - Yukon Gold (Russian)
@source:misc/xtom3d.cpp
xtom3d //
pumpit1 // (c) 1999 Andamiro
pumpitup // (c) 1999 Andamiro
xtom3d // (c) 1999 Andamiro
@source:misc/xyonix.cpp
xyonix // [1989 Philko]

View File

@ -4,6 +4,13 @@
Midway Quicksilver II/Graphite skeleton driver
TODO (BIOS):
- Accesses missing keyboard and RTC areas, needs to fix up Super I/O type;
- Currently used SMBus device EEPROM is incompatible with the BIOS used here, it expects a 4 to byte [0x02] (= SDRAM), there's no real code path for currently used DDR SDRAM setting.
Eventually will throw a "SPD device data missing or inconclusive."
- Several hang points before VGA drawing text, pinpoint them all;
- Detects a Pentium II at 700 MHz (?)
TODO:
- Fix HDD BAD_DUMPs ("primary master hard disk fail" in shutms11):
\- hydro -chs 392,255,63
@ -33,7 +40,8 @@ All of the games communicate with their I/O boards serially.
Quicksilver II hardware:
- Main CPU: Intel Celeron (Pentium II) 333/366MHz
- Motherboard: Intel SE440BX-2
- Motherboard: Intel SE440BX-2 "4S4EB2X0.86A.0017.P10"
https://theretroweb.com/motherboards/s/intel-se440bx-2-seattle-2
- RAM: 64MB PC100-222-620 non-ecc
- Sound: Integrated YMF740G
- Networking: SMC EZ Card 10 / SMC1208T (probably 10ec:8029 1113:1208)
@ -266,65 +274,54 @@ Notes:
#include "emu.h"
#include "pcshare.h"
#include "cpu/i386/i386.h"
#include "machine/lpci.h"
#include "machine/pckeybrd.h"
#include "machine/idectrl.h"
#include "video/pc_vga.h"
#include "machine/pci.h"
#include "machine/pci-ide.h"
#include "machine/pci-smbus.h"
#include "machine/i82443bx_host.h"
#include "machine/i82371eb_isa.h"
#include "machine/i82371eb_ide.h"
#include "machine/i82371eb_acpi.h"
#include "machine/i82371eb_usb.h"
#include "video/virge_pci.h"
#include "bus/isa/isa_cards.h"
//#include "bus/rs232/hlemouse.h"
//#include "bus/rs232/null_modem.h"
//#include "bus/rs232/rs232.h"
//#include "bus/rs232/sun_kbd.h"
//#include "bus/rs232/terminal.h"
#include "machine/fdc37c93x.h"
#include "video/voodoo_pci.h"
namespace {
class midway_quicksilver2_state : public pcat_base_state
#define PCI_J4D2_ID "pci:0d.0"
#define PCI_J4D1_ID "pci:0e.0"
#define PCI_J4C1_ID "pci:0f.0"
#define PCI_J4B1_ID "pci:10.0"
// J4E1
#define PCI_AGP_ID "pci:01.0:00.0"
class midway_quicksilver2_state : public driver_device
{
public:
midway_quicksilver2_state(const machine_config &mconfig, device_type type, const char *tag)
: pcat_base_state(mconfig, type, tag)
: driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
, m_voodoo2(*this, PCI_AGP_ID)
{
}
void midqslvr(machine_config &config);
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
private:
std::unique_ptr<uint32_t[]> m_bios_ram;
std::unique_ptr<uint32_t[]> m_bios_ext1_ram;
std::unique_ptr<uint32_t[]> m_bios_ext2_ram;
std::unique_ptr<uint32_t[]> m_bios_ext3_ram;
std::unique_ptr<uint32_t[]> m_bios_ext4_ram;
std::unique_ptr<uint32_t[]> m_isa_ram1;
std::unique_ptr<uint32_t[]> m_isa_ram2;
uint8_t m_mtxc_config_reg[256];
uint8_t m_piix4_config_reg[4][256];
required_device<pentium2_device> m_maincpu;
// optional for debugging ...
optional_device<voodoo_2_pci_device> m_voodoo2;
void isa_ram1_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
void isa_ram2_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
void bios_ext1_ram_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
void bios_ext2_ram_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
void bios_ext3_ram_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
void bios_ext4_ram_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
void bios_ram_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
void intel82439tx_init();
void midqslvr_io(address_map &map);
void midqslvr_map(address_map &map);
uint8_t mtxc_config_r(int function, int reg);
void mtxc_config_w(int function, int reg, uint8_t data);
uint32_t intel82439tx_pci_r(int function, int reg, uint32_t mem_mask);
void intel82439tx_pci_w(int function, int reg, uint32_t data, uint32_t mem_mask);
uint8_t piix4_config_r(int function, int reg);
void piix4_config_w(int function, int reg, uint8_t data);
uint32_t intel82371ab_pci_r(int function, int reg, uint32_t mem_mask);
void intel82371ab_pci_w(int function, int reg, uint32_t data, uint32_t mem_mask);
static void superio_config(device_t *device);
};
class midway_graphite_state : public driver_device
@ -338,368 +335,91 @@ public:
void graphite(machine_config &config);
private:
required_device<cpu_device> m_maincpu;
required_device<pentium3_device> m_maincpu;
void graphite_map(address_map &map);
};
// Intel 82439TX System Controller (MTXC)
uint8_t midway_quicksilver2_state::mtxc_config_r(int function, int reg)
{
// osd_printf_debug("MTXC: read %d, %02X\n", function, reg);
if((reg & 0xfc) == 0 && function == 0) // return vendor ID
return (0x71008086 >> (reg & 3)*8) & 0xff;
return m_mtxc_config_reg[reg];
}
void midway_quicksilver2_state::mtxc_config_w(int function, int reg, uint8_t data)
{
printf("MTXC: write %d, %02X, %02X\n", function, reg, data);
/*
memory banking with North Bridge:
0x59 (PAM0) xxxx ---- BIOS area 0xf0000-0xfffff
---- xxxx Reserved
0x5a (PAM1) xxxx ---- ISA add-on BIOS 0xc4000 - 0xc7fff
---- xxxx ISA add-on BIOS 0xc0000 - 0xc3fff
0x5b (PAM2) xxxx ---- ISA add-on BIOS 0xcc000 - 0xcffff
---- xxxx ISA add-on BIOS 0xc8000 - 0xcbfff
0x5c (PAM3) xxxx ---- ISA add-on BIOS 0xd4000 - 0xd7fff
---- xxxx ISA add-on BIOS 0xd0000 - 0xd3fff
0x5d (PAM4) xxxx ---- ISA add-on BIOS 0xdc000 - 0xdffff
---- xxxx ISA add-on BIOS 0xd8000 - 0xdbfff
0x5e (PAM5) xxxx ---- BIOS extension 0xe4000 - 0xe7fff
---- xxxx BIOS extension 0xe0000 - 0xe3fff
0x5f (PAM6) xxxx ---- BIOS extension 0xec000 - 0xeffff
---- xxxx BIOS extension 0xe8000 - 0xebfff
3210 -> 3 = reserved, 2 = Cache Enable, 1 = Write Enable, 0 = Read Enable
*/
switch(reg)
{
case 0x59: // PAM0
{
if (data & 0x10) // enable RAM access to region 0xf0000 - 0xfffff
membank("bios_bank")->set_base(m_bios_ram.get());
else // disable RAM access (reads go to BIOS ROM)
membank("bios_bank")->set_base(memregion("bios")->base() + 0x70000);
break;
}
case 0x5a: // PAM1
{
if (data & 0x1)
membank("video_bank1")->set_base(m_isa_ram1.get());
else
membank("video_bank1")->set_base(memregion("video_bios")->base() + 0);
if (data & 0x10)
membank("video_bank2")->set_base(m_isa_ram2.get());
else
membank("video_bank2")->set_base(memregion("video_bios")->base() + 0x4000);
break;
}
case 0x5e: // PAM5
{
if (data & 0x1)
membank("bios_ext1")->set_base(m_bios_ext1_ram.get());
else
membank("bios_ext1")->set_base(memregion("bios")->base() + 0x60000);
if (data & 0x10)
membank("bios_ext2")->set_base(m_bios_ext2_ram.get());
else
membank("bios_ext2")->set_base(memregion("bios")->base() + 0x64000);
break;
}
case 0x5f: // PAM6
{
if (data & 0x1)
membank("bios_ext3")->set_base(m_bios_ext3_ram.get());
else
membank("bios_ext3")->set_base(memregion("bios")->base() + 0x68000);
if (data & 0x10)
membank("bios_ext4")->set_base(m_bios_ext4_ram.get());
else
membank("bios_ext4")->set_base(memregion("bios")->base() + 0x6c000);
break;
}
}
m_mtxc_config_reg[reg] = data;
}
void midway_quicksilver2_state::intel82439tx_init()
{
m_mtxc_config_reg[0x60] = 0x02;
m_mtxc_config_reg[0x61] = 0x02;
m_mtxc_config_reg[0x62] = 0x02;
m_mtxc_config_reg[0x63] = 0x02;
m_mtxc_config_reg[0x64] = 0x02;
m_mtxc_config_reg[0x65] = 0x02;
}
uint32_t midway_quicksilver2_state::intel82439tx_pci_r(int function, int reg, uint32_t mem_mask)
{
uint32_t r = 0;
if (ACCESSING_BITS_24_31)
{
r |= mtxc_config_r(function, reg + 3) << 24;
}
if (ACCESSING_BITS_16_23)
{
r |= mtxc_config_r(function, reg + 2) << 16;
}
if (ACCESSING_BITS_8_15)
{
r |= mtxc_config_r(function, reg + 1) << 8;
}
if (ACCESSING_BITS_0_7)
{
r |= mtxc_config_r(function, reg + 0) << 0;
}
return r;
}
void midway_quicksilver2_state::intel82439tx_pci_w(int function, int reg, uint32_t data, uint32_t mem_mask)
{
if (ACCESSING_BITS_24_31)
{
mtxc_config_w(function, reg + 3, (data >> 24) & 0xff);
}
if (ACCESSING_BITS_16_23)
{
mtxc_config_w(function, reg + 2, (data >> 16) & 0xff);
}
if (ACCESSING_BITS_8_15)
{
mtxc_config_w(function, reg + 1, (data >> 8) & 0xff);
}
if (ACCESSING_BITS_0_7)
{
mtxc_config_w(function, reg + 0, (data >> 0) & 0xff);
}
}
// Intel 82371AB PCI-to-ISA / IDE bridge (PIIX4)
uint8_t midway_quicksilver2_state::piix4_config_r(int function, int reg)
{
function &= 3;
if((reg & 0xfc) == 0) // return vendor ID
return (((0x71108086 | (function & 3) << 16) >> (reg & 3)*8) & 0xff);
if(reg == 0xe)
{
const uint8_t header_type_val[4] = { 0x80, 0x00, 0x00, 0x00 };
return header_type_val[function];
}
if((reg & 0xfc) == 0x8)
{
/* TODO: reg 8 indicates Revision ID */
const uint32_t class_code_val[4] = { 0x06010000, 0x01018000, 0x0c030000, 0x06800000 };
return (((class_code_val[function]) >> (reg & 3)*8) & 0xff);
}
printf("%08x PIIX4: read %d, %02X\n", m_maincpu->pc(), function, reg);
return m_piix4_config_reg[function][reg];
}
void midway_quicksilver2_state::piix4_config_w(int function, int reg, uint8_t data)
{
printf("PIIX4: write %d, %02X, %02X\n", function, reg, data);
function &= 3;
m_piix4_config_reg[function][reg] = data;
}
uint32_t midway_quicksilver2_state::intel82371ab_pci_r(int function, int reg, uint32_t mem_mask)
{
uint32_t r = 0;
if (ACCESSING_BITS_24_31)
{
r |= piix4_config_r(function, reg + 3) << 24;
}
if (ACCESSING_BITS_16_23)
{
r |= piix4_config_r(function, reg + 2) << 16;
}
if (ACCESSING_BITS_8_15)
{
r |= piix4_config_r(function, reg + 1) << 8;
}
if (ACCESSING_BITS_0_7)
{
r |= piix4_config_r(function, reg + 0) << 0;
}
return r;
}
void midway_quicksilver2_state::intel82371ab_pci_w(int function, int reg, uint32_t data, uint32_t mem_mask)
{
if (ACCESSING_BITS_24_31)
{
piix4_config_w(function, reg + 3, (data >> 24) & 0xff);
}
if (ACCESSING_BITS_16_23)
{
piix4_config_w(function, reg + 2, (data >> 16) & 0xff);
}
if (ACCESSING_BITS_8_15)
{
piix4_config_w(function, reg + 1, (data >> 8) & 0xff);
}
if (ACCESSING_BITS_0_7)
{
piix4_config_w(function, reg + 0, (data >> 0) & 0xff);
}
}
void midway_quicksilver2_state::isa_ram1_w(offs_t offset, uint32_t data, uint32_t mem_mask)
{
if (m_mtxc_config_reg[0x5a] & 0x2) // write to RAM if this region is write-enabled
{
COMBINE_DATA(m_isa_ram1.get() + offset);
}
}
void midway_quicksilver2_state::isa_ram2_w(offs_t offset, uint32_t data, uint32_t mem_mask)
{
if (m_mtxc_config_reg[0x5a] & 0x2) // write to RAM if this region is write-enabled
{
COMBINE_DATA(m_isa_ram2.get() + offset);
}
}
void midway_quicksilver2_state::bios_ext1_ram_w(offs_t offset, uint32_t data, uint32_t mem_mask)
{
if (m_mtxc_config_reg[0x5e] & 0x2) // write to RAM if this region is write-enabled
{
COMBINE_DATA(m_bios_ext1_ram.get() + offset);
}
}
void midway_quicksilver2_state::bios_ext2_ram_w(offs_t offset, uint32_t data, uint32_t mem_mask)
{
if (m_mtxc_config_reg[0x5e] & 0x20) // write to RAM if this region is write-enabled
{
COMBINE_DATA(m_bios_ext2_ram.get() + offset);
}
}
void midway_quicksilver2_state::bios_ext3_ram_w(offs_t offset, uint32_t data, uint32_t mem_mask)
{
if (m_mtxc_config_reg[0x5f] & 0x2) // write to RAM if this region is write-enabled
{
COMBINE_DATA(m_bios_ext3_ram.get() + offset);
}
}
void midway_quicksilver2_state::bios_ext4_ram_w(offs_t offset, uint32_t data, uint32_t mem_mask)
{
if (m_mtxc_config_reg[0x5f] & 0x20) // write to RAM if this region is write-enabled
{
COMBINE_DATA(m_bios_ext4_ram.get() + offset);
}
}
void midway_quicksilver2_state::bios_ram_w(offs_t offset, uint32_t data, uint32_t mem_mask)
{
if (m_mtxc_config_reg[0x59] & 0x20) // write to RAM if this region is write-enabled
{
COMBINE_DATA(m_bios_ram.get() + offset);
}
}
void midway_quicksilver2_state::midqslvr_map(address_map &map)
{
map(0x00000000, 0x0009ffff).ram();
map(0x000a0000, 0x000bffff).rw("vga", FUNC(vga_device::mem_r), FUNC(vga_device::mem_w));
map(0x000c0000, 0x000c3fff).bankr("video_bank1").w(FUNC(midway_quicksilver2_state::isa_ram1_w));
map(0x000c4000, 0x000c7fff).bankr("video_bank2").w(FUNC(midway_quicksilver2_state::isa_ram2_w));
map(0x000e0000, 0x000e3fff).bankr("bios_ext1").w(FUNC(midway_quicksilver2_state::bios_ext1_ram_w));
map(0x000e4000, 0x000e7fff).bankr("bios_ext2").w(FUNC(midway_quicksilver2_state::bios_ext2_ram_w));
map(0x000e8000, 0x000ebfff).bankr("bios_ext3").w(FUNC(midway_quicksilver2_state::bios_ext3_ram_w));
map(0x000ec000, 0x000effff).bankr("bios_ext4").w(FUNC(midway_quicksilver2_state::bios_ext4_ram_w));
map(0x000f0000, 0x000fffff).bankr("bios_bank").w(FUNC(midway_quicksilver2_state::bios_ram_w));
map(0x00100000, 0x01ffffff).ram();
map(0xfff80000, 0xffffffff).rom().region("bios", 0); /* System BIOS */
map.unmap_value_high();
}
void midway_quicksilver2_state::midqslvr_io(address_map &map)
static void isa_internal_devices(device_slot_interface &device)
{
pcat32_io_common(map);
map(0x00e8, 0x00ef).noprw();
map(0x01f0, 0x01f7).rw("ide", FUNC(ide_controller_device::cs0_r), FUNC(ide_controller_device::cs0_w));
map(0x03b0, 0x03bf).rw("vga", FUNC(vga_device::port_03b0_r), FUNC(vga_device::port_03b0_w));
map(0x03c0, 0x03cf).rw("vga", FUNC(vga_device::port_03c0_r), FUNC(vga_device::port_03c0_w));
map(0x03d0, 0x03df).rw("vga", FUNC(vga_device::port_03d0_r), FUNC(vga_device::port_03d0_w));
map(0x03f0, 0x03f7).rw("ide", FUNC(ide_controller_device::cs1_r), FUNC(ide_controller_device::cs1_w));
map(0x0cf8, 0x0cff).rw("pcibus", FUNC(pci_bus_legacy_device::read), FUNC(pci_bus_legacy_device::write));
device.option_add("fdc37m707", FDC37M707);
}
void midway_quicksilver2_state::machine_start()
void midway_quicksilver2_state::superio_config(device_t *device)
{
m_bios_ram = std::make_unique<uint32_t[]>(0x10000/4);
m_bios_ext1_ram = std::make_unique<uint32_t[]>(0x4000/4);
m_bios_ext2_ram = std::make_unique<uint32_t[]>(0x4000/4);
m_bios_ext3_ram = std::make_unique<uint32_t[]>(0x4000/4);
m_bios_ext4_ram = std::make_unique<uint32_t[]>(0x4000/4);
m_isa_ram1 = std::make_unique<uint32_t[]>(0x4000/4);
m_isa_ram2 = std::make_unique<uint32_t[]>(0x4000/4);
intel82439tx_init();
}
void midway_quicksilver2_state::machine_reset()
{
membank("bios_bank")->set_base(memregion("bios")->base() + 0x70000);
membank("bios_ext1")->set_base(memregion("bios")->base() + 0x60000);
membank("bios_ext2")->set_base(memregion("bios")->base() + 0x64000);
membank("bios_ext3")->set_base(memregion("bios")->base() + 0x68000);
membank("bios_ext4")->set_base(memregion("bios")->base() + 0x6c000);
membank("video_bank1")->set_base(memregion("video_bios")->base() + 0);
membank("video_bank2")->set_base(memregion("video_bios")->base() + 0x4000);
fdc37m707_device &fdc = *downcast<fdc37m707_device *>(device);
fdc.set_sysopt_pin(0);
fdc.gp20_reset().set_inputline(":maincpu", INPUT_LINE_RESET);
fdc.gp25_gatea20().set_inputline(":maincpu", INPUT_LINE_A20);
fdc.irq1().set(":pci:07.0", FUNC(i82371eb_isa_device::pc_irq1_w));
fdc.irq8().set(":pci:07.0", FUNC(i82371eb_isa_device::pc_irq8n_w));
#if 0
fdc.txd1().set(":serport0", FUNC(rs232_port_device::write_txd));
fdc.ndtr1().set(":serport0", FUNC(rs232_port_device::write_dtr));
fdc.nrts1().set(":serport0", FUNC(rs232_port_device::write_rts));
fdc.txd2().set(":serport1", FUNC(rs232_port_device::write_txd));
fdc.ndtr2().set(":serport1", FUNC(rs232_port_device::write_dtr));
fdc.nrts2().set(":serport1", FUNC(rs232_port_device::write_rts));
#endif
}
void midway_quicksilver2_state::midqslvr(machine_config &config)
{
PENTIUM2(config, m_maincpu, 100'000'000); // Celeron, downclocked for debugging
m_maincpu->set_addrmap(AS_PROGRAM, &midway_quicksilver2_state::midqslvr_map);
m_maincpu->set_addrmap(AS_IO, &midway_quicksilver2_state::midqslvr_io);
m_maincpu->set_irq_acknowledge_callback("pic8259_1", FUNC(pic8259_device::inta_cb));
//m_maincpu->set_addrmap(AS_IO, &midway_quicksilver2_state::midqslvr_io);
m_maincpu->set_irq_acknowledge_callback("pci:07.0:pic8259_master", FUNC(pic8259_device::inta_cb));
m_maincpu->smiact().set("pci:00.0", FUNC(i82443bx_host_device::smi_act_w));
pcat_common(config);
PCI_ROOT(config, "pci", 0);
I82443BX_HOST(config, "pci:00.0", 0, "maincpu", 64*1024*1024);
I82443BX_BRIDGE(config, "pci:01.0", 0 ); //"pci:01.0:00.0");
//I82443BX_AGP (config, "pci:01.0:00.0");
pci_bus_legacy_device &pcibus(PCI_BUS_LEGACY(config, "pcibus", 0, 0));
pcibus.set_device( 0, FUNC(midway_quicksilver2_state::intel82439tx_pci_r), FUNC(midway_quicksilver2_state::intel82439tx_pci_w));
pcibus.set_device(31, FUNC(midway_quicksilver2_state::intel82371ab_pci_r), FUNC(midway_quicksilver2_state::intel82371ab_pci_w));
i82371eb_isa_device &isa(I82371EB_ISA(config, "pci:07.0", 0, m_maincpu));
isa.boot_state_hook().set([](u8 data) { /* printf("%02x\n", data); */ });
isa.smi().set_inputline("maincpu", INPUT_LINE_SMI);
ide_controller_device &ide(IDE_CONTROLLER(config, "ide").options(ata_devices, "hdd", nullptr, true));
ide.irq_handler().set("pic8259_2", FUNC(pic8259_device::ir6_w));
i82371eb_ide_device &ide(I82371EB_IDE(config, "pci:07.1", 0, m_maincpu));
ide.irq_pri().set("pci:07.0", FUNC(i82371eb_isa_device::pc_irq14_w));
ide.irq_sec().set("pci:07.0", FUNC(i82371eb_isa_device::pc_mirq0_w));
/* video hardware */
pcvideo_vga(config);
I82371EB_USB (config, "pci:07.2", 0);
I82371EB_ACPI(config, "pci:07.3", 0);
LPC_ACPI (config, "pci:07.3:acpi", 0);
SMBUS (config, "pci:07.3:smbus", 0);
ISA16_SLOT(config, "board4", 0, "pci:07.0:isabus", isa_internal_devices, "fdc37m707", true).set_option_machine_config("fdc37m707", superio_config);
ISA16_SLOT(config, "isa1", 0, "pci:07.0:isabus", pc_isa16_cards, nullptr, false);
ISA16_SLOT(config, "isa2", 0, "pci:07.0:isabus", pc_isa16_cards, nullptr, false);
// YMF740G goes thru "pci:0c.0"
// Expansion slots, mapping SVGA for debugging
// TODO: all untested, check clock
// TODO: confirm Voodoo going in AGP slot
#if 1
VOODOO_2_PCI(config, m_voodoo2, 0, m_maincpu, "screen"); // "pci:0d.0" J4D2
m_voodoo2->set_fbmem(2);
m_voodoo2->set_tmumem(4, 4);
m_voodoo2->set_status_cycles(1000);
// TODO: fix legacy raw setup here
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(57);
screen.set_size(640, 480);
screen.set_visarea(0, 640 - 1, 0, 480 - 1);
screen.set_screen_update(PCI_AGP_ID, FUNC(voodoo_2_pci_device::screen_update));
#endif
// "pci:0d.0" J4D2
// "pci:0e.0" J4D1
VIRGE_PCI(config, "pci:0e.0", 0); // J4C1
}
// Graphite runs on incompatible HW, consider splitting if things starts to get hairy ...
@ -723,52 +443,40 @@ void midway_graphite_state::graphite(machine_config &config)
ROM_START( hydrthnd )
ROM_REGION32_LE(0x80000, "bios", 0)
ROM_REGION32_LE(0x80000, "pci:07.0", 0)
ROM_LOAD( "lh28f004sct.u8b1", 0x000000, 0x080000, CRC(ab04a343) SHA1(ba77933400fe470f45ab187bc0d315922caadb12) )
ROM_REGION( 0x8000, "video_bios", ROMREGION_ERASEFF ) // TODO: Voodoo 2 has no bios, to be removed once the driver is updated not to look for this region
// ROM_LOAD16_BYTE( "trident_tgui9680_bios.bin", 0x0000, 0x4000, BAD_DUMP CRC(1eebde64) SHA1(67896a854d43a575037613b3506aea6dae5d6a19) )
// ROM_CONTINUE( 0x0001, 0x4000 )
ROM_REGION( 0x2000, "iocpu", 0 ) /* Diego board CY7C63513 MCU code */
ROM_LOAD( "diego.u8", 0x0000, 0x2000, NO_DUMP ) // 8KB internal EPROM
DISK_REGION( "ide:0:hdd" )
DISK_REGION( "pci:07.1:ide1:0:hdd" )
DISK_IMAGE( "hydro", 0, BAD_DUMP SHA1(d481d178782943c066b41764628a419cd55f676d) )
ROM_END
ROM_START( hydrthnd101b )
ROM_REGION32_LE(0x80000, "bios", 0)
ROM_REGION32_LE(0x80000, "pci:07.0", 0)
ROM_LOAD( "lh28f004sct.u8b1", 0x000000, 0x080000, CRC(ab04a343) SHA1(ba77933400fe470f45ab187bc0d315922caadb12) )
ROM_REGION( 0x8000, "video_bios", ROMREGION_ERASEFF ) // TODO: Voodoo 2 has no bios, to be removed once the driver is updated not to look for this region
// ROM_LOAD16_BYTE( "trident_tgui9680_bios.bin", 0x0000, 0x4000, BAD_DUMP CRC(1eebde64) SHA1(67896a854d43a575037613b3506aea6dae5d6a19) )
// ROM_CONTINUE( 0x0001, 0x4000 )
ROM_REGION( 0x2000, "iocpu", 0 ) /* Diego board CY7C63513 MCU code */
ROM_LOAD( "diego.u8", 0x0000, 0x2000, NO_DUMP ) // 8KB internal EPROM
DISK_REGION( "ide:0:hdd" )
DISK_REGION( "pci:07.1:ide1:0:hdd" )
DISK_IMAGE( "hydro_101b", 0, SHA1(182a7966c40676031c92dbfbd1b8e594a505a930) )
ROM_END
ROM_START( hydrthnd100d )
ROM_REGION32_LE(0x80000, "bios", 0)
ROM_REGION32_LE(0x80000, "pci:07.0", 0)
ROM_LOAD( "lh28f004sct.u8b1", 0x000000, 0x080000, CRC(ab04a343) SHA1(ba77933400fe470f45ab187bc0d315922caadb12) )
ROM_REGION( 0x8000, "video_bios", ROMREGION_ERASEFF ) // TODO: Voodoo 2 has no bios, to be removed once the driver is updated not to look for this region
// ROM_LOAD16_BYTE( "trident_tgui9680_bios.bin", 0x0000, 0x4000, BAD_DUMP CRC(1eebde64) SHA1(67896a854d43a575037613b3506aea6dae5d6a19) )
// ROM_CONTINUE( 0x0001, 0x4000 )
ROM_REGION( 0x2000, "iocpu", 0 ) /* Diego board CY7C63513 MCU code */
ROM_LOAD( "diego.u8", 0x0000, 0x2000, NO_DUMP ) // 8KB internal EPROM
DISK_REGION( "ide:0:hdd" )
DISK_REGION( "pci:07.1:ide1:0:hdd" )
DISK_IMAGE( "hydro_100d", 0, SHA1(5462f7197b3c510b791093e938a614e706aaed4a) )
ROM_END
ROM_START( offrthnd )
ROM_REGION32_LE(0x80000, "bios", 0)
ROM_REGION32_LE(0x80000, "pci:07.0", 0)
ROM_LOAD( "lh28f004sct.u8b1", 0x000000, 0x080000, CRC(ab04a343) SHA1(ba77933400fe470f45ab187bc0d315922caadb12) )
ROM_REGION( 0x8000, "video_bios", ROMREGION_ERASEFF ) // TODO: Voodoo 2 has no bios, to be removed once the driver is updated not to look for this region
@ -778,7 +486,7 @@ ROM_START( offrthnd )
ROM_REGION( 0x2000, "iocpu", 0 ) /* Magicbus board CY7C63513 MCU code */
ROM_LOAD( "magicbus.u18", 0x0000, 0x2000, NO_DUMP ) // 8KB internal EPROM
DISK_REGION( "ide:0:hdd" )
DISK_REGION( "pci:07.1:ide1:0:hdd" )
DISK_IMAGE( "offrthnd", 0, BAD_DUMP SHA1(d88f1c5b75361a1e310565a8a5a09c674a4a1a22) )
ROM_END
@ -793,7 +501,7 @@ ROM_START( arctthnd )
ROM_REGION( 0x2000, "iocpu", 0 ) /* Substitute board 87C552 MCU code */
ROM_LOAD( "87c552.bin", 0x0000, 0x2000, NO_DUMP ) // 8KB internal EPROM
DISK_REGION( "ide:0:hdd" )
DISK_REGION( "pci:07.1:ide1:0:hdd" )
DISK_IMAGE( "arctthnd", 0, SHA1(f4373e57c3f453ac09c735b5d8d99ff811416a23) )
ROM_END
@ -808,7 +516,7 @@ ROM_START( ultarctc )
ROM_REGION( 0x2000, "iocpu", 0 ) /* Substitute board 87C552 MCU code */
ROM_LOAD( "87c552.bin", 0x0000, 0x2000, NO_DUMP ) // 8KB internal EPROM
DISK_REGION( "ide:0:hdd" )
DISK_REGION( "pci:07.1:ide1:0:hdd" )
DISK_IMAGE( "uarctict", 0, SHA1(8557a1d7ae8dc41c879350cb1c228f4c27a0dd09) )
ROM_END
@ -826,11 +534,12 @@ ROM_START( ultarctcup )
ROM_REGION( 0x2000, "iocpu", 0 ) /* Substitute board 87C552 MCU code */
ROM_LOAD( "87c552.bin", 0x0000, 0x2000, NO_DUMP ) // 8KB internal EPROM
DISK_REGION( "ide:0:hdd" )
DISK_REGION( "pci:07.1:ide1:0:hdd" )
DISK_IMAGE( "uarctict", 0, SHA1(8557a1d7ae8dc41c879350cb1c228f4c27a0dd09) )
// TODO: eventually needs mountable option
DISK_REGION( "cd" )
DISK_IMAGE( "040503_1309", 0, SHA1(453adb81e204b0580ad02c2d98f68525757ec2a1) )
DISK_IMAGE_READONLY( "040503_1309", 0, SHA1(453adb81e204b0580ad02c2d98f68525757ec2a1) )
// sourced from these
// ROM_LOAD( "040503_1309.CUE", 0x0000, 0x000004d, CRC(4a9e2de5) SHA1(04d3d90ad4b235c0ac4606557e16a1410d018fa9) )
// ROM_LOAD( "040503_1309.BIN", 0x0000, 0x6bd9960, CRC(48a63422) SHA1(9d1cacf07526c5bddf4205c667a9010802f74859) )

View File

@ -1,12 +1,15 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
// copyright-holders:Ryan Holtz, Angelo Salese
/* Come On Baby
(c) 2000 ExPotato Co. Ltd (Excellent Potato)
TODO:
- skeleton driver;
- Throws "Primary master hard disk fail" in shutms11. Disk has a non canonical -chs of 524,255,63.
winimage will throw plenty of errors on manual file extraction.
winimage will throw plenty of errors on manual file extraction (related to Korean paths?).
- Currently needs enabled_logical true in super I/O handling (needs the real
ITE Giga I/O to fix);
- In this driver with a manually rebuilt image will loop during the fake "now loading" screen
(customized Win 98 splash screen);
- In pcipc with a manually rebuilt image will throw an exception in "Internat" module once it loads
Windows 98 (and installs the diff drivers).
@ -189,54 +192,142 @@ TODO:
#include "emu.h"
#include "cpu/i386/i386.h"
#include "machine/pci.h"
#include "machine/pci-ide.h"
#include "machine/i82443bx_host.h"
#include "machine/i82371eb_isa.h"
#include "machine/i82371eb_ide.h"
#include "machine/i82371eb_acpi.h"
#include "machine/i82371eb_usb.h"
#include "video/virge_pci.h"
#include "bus/isa/isa_cards.h"
//#include "bus/rs232/hlemouse.h"
//#include "bus/rs232/null_modem.h"
//#include "bus/rs232/rs232.h"
//#include "bus/rs232/sun_kbd.h"
//#include "bus/rs232/terminal.h"
#include "machine/fdc37c93x.h"
#include "video/voodoo_pci.h"
#define ENABLE_VOODOO 0
namespace {
#define PCI_AGP_ID "pci:01.0:00.0"
class comebaby_state : public driver_device
{
public:
comebaby_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
, m_voodoo3(*this, PCI_AGP_ID)
{ }
void comebaby(machine_config &config);
private:
required_device<cpu_device> m_maincpu;
required_device<pentium2_device> m_maincpu;
// optional for making the compile switch to work
optional_device<voodoo_3_pci_device> m_voodoo3;
void comebaby_map(address_map &map);
static void superio_config(device_t *device);
};
void comebaby_state::comebaby_map(address_map &map)
{
map(0x00000000, 0x0009ffff).ram();
// map(0x000a0000, 0x000bffff).ram();
map(0x000e0000, 0x000fffff).rom().region("bios", 0x20000);
map(0xfffc0000, 0xffffffff).rom().region("bios", 0);
map.unmap_value_high();
}
static INPUT_PORTS_START( comebaby )
INPUT_PORTS_END
static void isa_internal_devices(device_slot_interface &device)
{
device.option_add("fdc37c93x", FDC37C93X);
}
void comebaby_state::superio_config(device_t *device)
{
// TODO: wrong super I/O type
// It's an ITE 8671 "Giga I/O", unemulated
fdc37c93x_device &fdc = *downcast<fdc37c93x_device *>(device);
fdc.set_sysopt_pin(0);
fdc.gp20_reset().set_inputline(":maincpu", INPUT_LINE_RESET);
fdc.gp25_gatea20().set_inputline(":maincpu", INPUT_LINE_A20);
fdc.irq1().set(":pci:07.0", FUNC(i82371eb_isa_device::pc_irq1_w));
fdc.irq8().set(":pci:07.0", FUNC(i82371eb_isa_device::pc_irq8n_w));
#if 0
fdc.txd1().set(":serport0", FUNC(rs232_port_device::write_txd));
fdc.ndtr1().set(":serport0", FUNC(rs232_port_device::write_dtr));
fdc.nrts1().set(":serport0", FUNC(rs232_port_device::write_rts));
fdc.txd2().set(":serport1", FUNC(rs232_port_device::write_txd));
fdc.ndtr2().set(":serport1", FUNC(rs232_port_device::write_dtr));
fdc.nrts2().set(":serport1", FUNC(rs232_port_device::write_rts));
#endif
}
// TODO: unverified PCI config space
void comebaby_state::comebaby(machine_config &config)
{
/* basic machine hardware */
PENTIUM2(config, m_maincpu, 66'666'666); /* Actually a Celeron (66'666'666 * 19) / 2 */
PENTIUM2(config, m_maincpu, 66'666'666); // Actually a Celeron (66'666'666 * 19) / 2
m_maincpu->set_addrmap(AS_PROGRAM, &comebaby_state::comebaby_map);
//m_maincpu->set_addrmap(AS_IO, &comebaby_state::comebaby_io);
m_maincpu->set_irq_acknowledge_callback("pci:07.0:pic8259_master", FUNC(pic8259_device::inta_cb));
m_maincpu->smiact().set("pci:00.0", FUNC(i82443bx_host_device::smi_act_w));
PCI_ROOT(config, "pci", 0);
// ...
I82443BX_HOST(config, "pci:00.0", 0, "maincpu", 64*1024*1024);
I82443BX_BRIDGE(config, "pci:01.0", 0 ); //"pci:01.0:00.0");
//I82443BX_AGP (config, "pci:01.0:00.0");
i82371eb_isa_device &isa(I82371EB_ISA(config, "pci:07.0", 0, m_maincpu));
isa.boot_state_hook().set([](u8 data) { /* printf("%02x\n", data); */ });
isa.smi().set_inputline("maincpu", INPUT_LINE_SMI);
i82371eb_ide_device &ide(I82371EB_IDE(config, "pci:07.1", 0, m_maincpu));
ide.irq_pri().set("pci:07.0", FUNC(i82371eb_isa_device::pc_irq14_w));
ide.irq_sec().set("pci:07.0", FUNC(i82371eb_isa_device::pc_mirq0_w));
I82371EB_USB (config, "pci:07.2", 0);
I82371EB_ACPI(config, "pci:07.3", 0);
LPC_ACPI (config, "pci:07.3:acpi", 0);
SMBUS (config, "pci:07.3:smbus", 0);
ISA16_SLOT(config, "board4", 0, "pci:07.0:isabus", isa_internal_devices, "fdc37c93x", true).set_option_machine_config("fdc37c93x", superio_config);
ISA16_SLOT(config, "isa1", 0, "pci:07.0:isabus", pc_isa16_cards, nullptr, false);
ISA16_SLOT(config, "isa2", 0, "pci:07.0:isabus", pc_isa16_cards, nullptr, false);
// YMF740G goes thru "pci:0c.0"
// Expansion slots, mapping SVGA for debugging
// TODO: all untested, check clock
#if ENABLE_VOODOO
VOODOO_3_PCI(config, m_voodoo3, 0, m_maincpu, "screen"); // "pci:0d.0" J4D2
m_voodoo3->set_fbmem(2);
m_voodoo3->set_tmumem(4, 4);
m_voodoo3->set_status_cycles(1000);
// TODO: fix legacy raw setup here
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(57);
screen.set_size(640, 480);
screen.set_visarea(0, 640 - 1, 0, 480 - 1);
screen.set_screen_update(PCI_AGP_ID, FUNC(voodoo_3_pci_device::screen_update));
#else
// "pci:0d.0" J4D2
// "pci:0e.0" J4D1
VIRGE_PCI(config, "pci:0e.0", 0); // J4C1
#endif
}
ROM_START(comebaby)
ROM_REGION32_LE(0x40000, "bios", 0) /* motherboard bios */
ROM_REGION32_LE(0x40000, "pci:07.0", 0) /* motherboard bios */
ROM_LOAD("b1120iag.bin", 0x000000, 0x40000, CRC(9b6f95f1) SHA1(65d6a2fea9911593f093b2e2a43d1534b54d60b3) )
DISK_REGION( "disks" )
DISK_REGION( "pci:07.1:ide1:0:hdd" )
DISK_IMAGE( "comebaby", 0, BAD_DUMP SHA1(ea57919319c0b6a1d4abd7822cff028855bf082f) )
ROM_END

View File

@ -1,14 +1,38 @@
// license:BSD-3-Clause
// copyright-holders:Guru
// copyright-holders:Guru, Angelo Salese
/**************************************************************************************************
X Tom 3D
Customized i440bx Award based BIOS, "OKSAN MK III /EVATE Ver99.04.20"
"04/20/1999-i440BX-2A69KEIC-00"
TODO:
- clears a work RAM snippet then jumps to that snippet ... it doesn't do
that if you soft reset emulation.
- understand how to load game ROMs. u3 contains a FAT12 file system for DOS/Windows
partition.
- DIR texture folder will throw mangled file structure the second time around (when
ENABLE_VOODOO is 0 and SVGA is used instead). PAM[5] and [6] areas are written to but
they are locked for write ...
- Voodoo Banshee doesn't handle VGA text modes correctly, it will set the screen to 80 x 25
at POST (making MAME UI host to be unusable) without any drawing.
Current stall point (texture init) will eventually write data at VGA memory $a0000-$bffff,
likely for drawing an error.
- Pinpoint what i/o $2a8 is for during texture init (alt serial flash transfer?)
- EEPROM (i/o $2ac r/w)
- Hookup ISA sound board (YMZ280B + YAC516 + 3550A DAC);
- pumpit1: MSCDEX hangs often when Voodoo is disabled;
- pumpit1: black screens all the way with Voodoo enabled, eventually throws a fatal error
"pci:01.0:00.0:voodoo: Unsupported cmdFifo packet type 7", may require true AGP comms or properly initialized SPD DIMMs;
- Pump it Up: every CD after pumpit1 are really multisession disks, which is unsupported
by chdman at the time of this writing (and doesn't seem worth converting atm);
- Pump it Up: CAT702 ZN protection for later games;
- MAS 3507D MP3 decoder for pumpito and beyond;
Notes:
- Oksan is the old company name that became Andamiro.
- Pump It Up refs:
https://github.com/pumpitupdev/pumptools/blob/master/doc/hook/mk3hook.md
https://github.com/Shizmob/arcade-docs/blob/main/andamiro/board.md#mk3
===================================================================================================
This game runs on PC-based hardware.
Major components are....
@ -42,422 +66,406 @@ MX29F1610MC 16M FlashROM (x7)
#include "emu.h"
#include "pcshare.h"
#include "cpu/i386/i386.h"
#include "machine/lpci.h"
#include "machine/pckeybrd.h"
#include "machine/idectrl.h"
#include "video/pc_vga.h"
#include "machine/pci.h"
#include "machine/pci-ide.h"
#include "machine/pci-smbus.h"
#include "machine/i82443bx_host.h"
#include "machine/i82371eb_isa.h"
#include "machine/i82371eb_ide.h"
#include "machine/i82371eb_acpi.h"
#include "machine/i82371eb_usb.h"
#include "video/virge_pci.h"
#include "bus/isa/isa.h"
#include "bus/isa/isa_cards.h"
//#include "bus/rs232/hlemouse.h"
//#include "bus/rs232/null_modem.h"
//#include "bus/rs232/rs232.h"
//#include "bus/rs232/sun_kbd.h"
//#include "bus/rs232/terminal.h"
//#include "machine/fdc37c93x.h"
#include "machine/mc146818.h"
#include "machine/8042kbdc.h"
#include "video/voodoo_pci.h"
#define ENABLE_VOODOO 1
/*
* ISA16 Oksan ROM DISK
*
* "OKSAN (R) ROM DISK for MK-III Version 1.00.0305"
* "Copyright (C) OKSAN Co., Ltd. 1989-1999" (!)
*
*/
class isa16_oksan_rom_disk : public device_t, public device_isa16_card_interface
{
public:
// construction/destruction
isa16_oksan_rom_disk(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
template <typename T> void set_rom_tag(T &&tag) { m_flash_rom.set_tag(std::forward<T>(tag)); }
protected:
virtual void device_start() override;
virtual void device_reset() override;
private:
required_memory_region m_flash_rom;
u8 read(offs_t offset);
void write(offs_t offset, u8 data);
void remap(int space_id, offs_t start, offs_t end) override;
u8 m_flash_cmd = 0;
u32 m_flash_addr = 0;
bool m_flash_unlock = false;
u8 m_flash_state = 0;
};
DEFINE_DEVICE_TYPE(ISA16_OKSAN_ROM_DISK, isa16_oksan_rom_disk, "isa16_oksan_rom_disk", "ISA16 Oksan ROM DISK for MK-III")
isa16_oksan_rom_disk::isa16_oksan_rom_disk(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, ISA16_OKSAN_ROM_DISK, tag, owner, clock)
, device_isa16_card_interface(mconfig, *this)
, m_flash_rom(*this, finder_base::DUMMY_TAG)
{
}
void isa16_oksan_rom_disk::device_start()
{
set_isa_device();
}
void isa16_oksan_rom_disk::device_reset()
{
m_flash_state = 0;
}
void isa16_oksan_rom_disk::remap(int space_id, offs_t start, offs_t end)
{
if (space_id == AS_IO)
{
m_isa->install_device(0x02d0, 0x02df, read8sm_delegate(*this, FUNC(isa16_oksan_rom_disk::read)), write8sm_delegate(*this, FUNC(isa16_oksan_rom_disk::write)));
}
}
// TODO: quick and dirty MX29F1610MC serial flash ROM implementation
// should really be a serflash_device inheritance ...
u8 isa16_oksan_rom_disk::read(offs_t offset)
{
//printf("%02x\n", offset);
if (offset == 0xa || offset == 0xb)
{
if (m_flash_cmd == 0xf0 && m_flash_unlock)
{
const u32 flash_size = m_flash_rom->bytes() - 1;
u8 rom_data = m_flash_rom->base()[((m_flash_addr << 1) + (offset & 1)) & flash_size];
if (offset & 1 && !machine().side_effects_disabled())
m_flash_addr ++;
return rom_data;
}
}
return 0;
}
void isa16_oksan_rom_disk::write(offs_t offset, u8 data)
{
// if (offset < 8 && ((offset & 1) == 0) && m_flash_cmd == 0xf0)
// printf("%04x %04x \n", offset, data);
switch(offset)
{
// address port
case 0x0:
m_flash_addr &= 0xffffff00;
m_flash_addr |= data & 0xff;
break;
case 0x2:
m_flash_addr &= 0xffff00ff;
m_flash_addr |= (data & 0xff) << 8;
break;
case 0x4:
//if (data)
// printf("%02x\n", data);
m_flash_addr &= 0xff00ffff;
m_flash_addr |= (data & 0xff) << 16;
break;
case 0x6:
m_flash_addr &= 0x00ffffff;
m_flash_addr |= (data & 0xff) << 24;
break;
// data port
case 0xa:
if (data == 0xaa && m_flash_addr == 0x5555 && m_flash_state == 0)
{
m_flash_state = 1;
}
else if (data == 0x55 && m_flash_addr == 0x2aaa && m_flash_state == 1)
m_flash_state = 2;
else if (m_flash_state == 2 && m_flash_addr == 0x5555)
{
m_flash_state = 0;
m_flash_cmd = data;
//printf("%02x %08x\n", data, m_flash_addr);
}
break;
// chip enable, 0 -> 1 transitions
case 0xc:
m_flash_unlock = bool(BIT(data, 3));
break;
}
}
/*
* ISA16 Oksan Virtual LPC
*
* Doesn't really accesses a Super I/O, which implies that the Holtek keyboard
* and the RTC chips are motherboard ISA resources.
*
*/
class isa16_oksan_lpc : public device_t, public device_isa16_card_interface
{
public:
// construction/destruction
isa16_oksan_lpc(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
required_device<mc146818_device> m_rtc;
required_device<kbdc8042_device> m_kbdc;
protected:
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_add_mconfig(machine_config &config) override;
private:
void remap(int space_id, offs_t start, offs_t end) override;
};
DEFINE_DEVICE_TYPE(ISA16_OKSAN_LPC, isa16_oksan_lpc, "isa16_oksan_lpc", "ISA16 Oksan Virtual LPC")
isa16_oksan_lpc::isa16_oksan_lpc(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, ISA16_OKSAN_LPC, tag, owner, clock)
, device_isa16_card_interface(mconfig, *this)
, m_rtc(*this, "rtc")
, m_kbdc(*this, "kbdc")
{
}
void isa16_oksan_lpc::device_add_mconfig(machine_config &config)
{
MC146818(config, m_rtc, 32.768_kHz_XTAL);
//m_rtc->irq().set(m_pic8259_2, FUNC(pic8259_device::ir0_w));
m_rtc->set_century_index(0x32);
KBDC8042(config, m_kbdc, 0);
m_kbdc->set_keyboard_type(kbdc8042_device::KBDC8042_STANDARD);
m_kbdc->system_reset_callback().set_inputline(":maincpu", INPUT_LINE_RESET);
m_kbdc->gate_a20_callback().set_inputline(":maincpu", INPUT_LINE_A20);
m_kbdc->input_buffer_full_callback().set(":pci:07.0", FUNC(i82371sb_isa_device::pc_irq1_w));
}
void isa16_oksan_lpc::device_start()
{
set_isa_device();
}
void isa16_oksan_lpc::device_reset()
{
}
void isa16_oksan_lpc::remap(int space_id, offs_t start, offs_t end)
{
if (space_id == AS_IO)
{
m_isa->install_device(0x60, 0x6f, read8sm_delegate(m_kbdc, FUNC(kbdc8042_device::data_r)), write8sm_delegate(m_kbdc, FUNC(kbdc8042_device::data_w)));
m_isa->install_device(0x70, 0x7f, read8sm_delegate(m_rtc, FUNC(mc146818_device::read)), write8sm_delegate(m_rtc, FUNC(mc146818_device::write)));
}
}
namespace {
class xtom3d_state : public pcat_base_state
#define PCI_AGP_ID "pci:01.0:00.0"
#define PCI_IDE_ID "pci:07.1"
class xtom3d_state : public driver_device
{
public:
xtom3d_state(const machine_config &mconfig, device_type type, const char *tag)
: pcat_base_state(mconfig, type, tag)
, m_pcibus(*this, "pcibus")
: driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
, m_voodoo(*this, PCI_AGP_ID)
, m_pci_isa(*this, "pci:07.0")
{
}
void xtom3d(machine_config &config);
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
private:
std::unique_ptr<uint32_t[]> m_bios_ram;
std::unique_ptr<uint32_t[]> m_bios_ext1_ram;
std::unique_ptr<uint32_t[]> m_bios_ext2_ram;
std::unique_ptr<uint32_t[]> m_bios_ext3_ram;
std::unique_ptr<uint32_t[]> m_bios_ext4_ram;
std::unique_ptr<uint32_t[]> m_isa_ram1;
std::unique_ptr<uint32_t[]> m_isa_ram2;
uint8_t m_mtxc_config_reg[256];
uint8_t m_piix4_config_reg[4][256];
required_device<pentium2_device> m_maincpu;
// TODO: optional for debugging
optional_device<voodoo_banshee_pci_device> m_voodoo;
required_device<i82371eb_isa_device> m_pci_isa;
void isa_ram1_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
void isa_ram2_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
void bios_ext1_ram_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
void bios_ext2_ram_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
void bios_ext3_ram_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
void bios_ext4_ram_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
void bios_ram_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
void intel82439tx_init();
void xtom3d_io(address_map &map);
void xtom3d_map(address_map &map);
// void xtom3d_io(address_map &map);
uint8_t mtxc_config_r(int function, int reg);
void mtxc_config_w(int function, int reg, uint8_t data);
uint32_t intel82439tx_pci_r(int function, int reg, uint32_t mem_mask);
void intel82439tx_pci_w(int function, int reg, uint32_t data, uint32_t mem_mask);
uint8_t piix4_config_r(int function, int reg);
void piix4_config_w(int function, int reg, uint8_t data);
uint32_t intel82371ab_pci_r(int function, int reg, uint32_t mem_mask);
void intel82371ab_pci_w(int function, int reg, uint32_t data, uint32_t mem_mask);
// DECLARE_WRITE_LINE_MEMBER(vblank_assert);
required_device<pci_bus_legacy_device> m_pcibus;
static void romdisk_config(device_t *device);
// static void cdrom_config(device_t *device);
};
// Intel 82439TX System Controller (MTXC)
uint8_t xtom3d_state::mtxc_config_r(int function, int reg)
{
// osd_printf_debug("MTXC: read %d, %02X\n", function, reg);
return m_mtxc_config_reg[reg];
}
void xtom3d_state::mtxc_config_w(int function, int reg, uint8_t data)
{
printf("MTXC: write %d, %02X, %02X\n", function, reg, data);
/*
memory banking with North Bridge:
0x59 (PAM0) xxxx ---- BIOS area 0xf0000-0xfffff
---- xxxx Reserved
0x5a (PAM1) xxxx ---- ISA add-on BIOS 0xc4000 - 0xc7fff
---- xxxx ISA add-on BIOS 0xc0000 - 0xc3fff
0x5b (PAM2) xxxx ---- ISA add-on BIOS 0xcc000 - 0xcffff
---- xxxx ISA add-on BIOS 0xc8000 - 0xcbfff
0x5c (PAM3) xxxx ---- ISA add-on BIOS 0xd4000 - 0xd7fff
---- xxxx ISA add-on BIOS 0xd0000 - 0xd3fff
0x5d (PAM4) xxxx ---- ISA add-on BIOS 0xdc000 - 0xdffff
---- xxxx ISA add-on BIOS 0xd8000 - 0xdbfff
0x5e (PAM5) xxxx ---- BIOS extension 0xe4000 - 0xe7fff
---- xxxx BIOS extension 0xe0000 - 0xe3fff
0x5f (PAM6) xxxx ---- BIOS extension 0xec000 - 0xeffff
---- xxxx BIOS extension 0xe8000 - 0xebfff
3210 -> 3 = reserved, 2 = Cache Enable, 1 = Write Enable, 0 = Read Enable
*/
switch(reg)
{
case 0x59: // PAM0
{
if (data & 0x10) // enable RAM access to region 0xf0000 - 0xfffff
membank("bios_bank")->set_base(m_bios_ram.get());
else // disable RAM access (reads go to BIOS ROM)
membank("bios_bank")->set_base(memregion("bios")->base() + 0x10000);
break;
}
case 0x5a: // PAM1
{
if (data & 0x1)
membank("video_bank1")->set_base(m_isa_ram1.get());
else
membank("video_bank1")->set_base(memregion("video_bios")->base() + 0);
if (data & 0x10)
membank("video_bank2")->set_base(m_isa_ram2.get());
else
membank("video_bank2")->set_base(memregion("video_bios")->base() + 0x4000);
break;
}
case 0x5e: // PAM5
{
if (data & 0x1)
membank("bios_ext1")->set_base(m_bios_ext1_ram.get());
else
membank("bios_ext1")->set_base(memregion("bios")->base() + 0);
if (data & 0x10)
membank("bios_ext2")->set_base(m_bios_ext2_ram.get());
else
membank("bios_ext2")->set_base(memregion("bios")->base() + 0x4000);
break;
}
case 0x5f: // PAM6
{
if (data & 0x1)
membank("bios_ext3")->set_base(m_bios_ext3_ram.get());
else
membank("bios_ext3")->set_base(memregion("bios")->base() + 0x8000);
if (data & 0x10)
membank("bios_ext4")->set_base(m_bios_ext4_ram.get());
else
membank("bios_ext4")->set_base(memregion("bios")->base() + 0xc000);
break;
}
}
m_mtxc_config_reg[reg] = data;
}
void xtom3d_state::intel82439tx_init()
{
m_mtxc_config_reg[0x60] = 0x02;
m_mtxc_config_reg[0x61] = 0x02;
m_mtxc_config_reg[0x62] = 0x02;
m_mtxc_config_reg[0x63] = 0x02;
m_mtxc_config_reg[0x64] = 0x02;
m_mtxc_config_reg[0x65] = 0x02;
}
uint32_t xtom3d_state::intel82439tx_pci_r(int function, int reg, uint32_t mem_mask)
{
uint32_t r = 0;
if (ACCESSING_BITS_24_31)
{
r |= mtxc_config_r(function, reg + 3) << 24;
}
if (ACCESSING_BITS_16_23)
{
r |= mtxc_config_r(function, reg + 2) << 16;
}
if (ACCESSING_BITS_8_15)
{
r |= mtxc_config_r(function, reg + 1) << 8;
}
if (ACCESSING_BITS_0_7)
{
r |= mtxc_config_r(function, reg + 0) << 0;
}
return r;
}
void xtom3d_state::intel82439tx_pci_w(int function, int reg, uint32_t data, uint32_t mem_mask)
{
if (ACCESSING_BITS_24_31)
{
mtxc_config_w(function, reg + 3, (data >> 24) & 0xff);
}
if (ACCESSING_BITS_16_23)
{
mtxc_config_w(function, reg + 2, (data >> 16) & 0xff);
}
if (ACCESSING_BITS_8_15)
{
mtxc_config_w(function, reg + 1, (data >> 8) & 0xff);
}
if (ACCESSING_BITS_0_7)
{
mtxc_config_w(function, reg + 0, (data >> 0) & 0xff);
}
}
// Intel 82371AB PCI-to-ISA / IDE bridge (PIIX4)
uint8_t xtom3d_state::piix4_config_r(int function, int reg)
{
// osd_printf_debug("PIIX4: read %d, %02X\n", function, reg);
return m_piix4_config_reg[function][reg];
}
void xtom3d_state::piix4_config_w(int function, int reg, uint8_t data)
{
// osd_printf_debug("%s:PIIX4: write %d, %02X, %02X\n", machine().describe_context(), function, reg, data);
m_piix4_config_reg[function][reg] = data;
}
uint32_t xtom3d_state::intel82371ab_pci_r(int function, int reg, uint32_t mem_mask)
{
uint32_t r = 0;
if (ACCESSING_BITS_24_31)
{
r |= piix4_config_r(function, reg + 3) << 24;
}
if (ACCESSING_BITS_16_23)
{
r |= piix4_config_r(function, reg + 2) << 16;
}
if (ACCESSING_BITS_8_15)
{
r |= piix4_config_r(function, reg + 1) << 8;
}
if (ACCESSING_BITS_0_7)
{
r |= piix4_config_r(function, reg + 0) << 0;
}
return r;
}
void xtom3d_state::intel82371ab_pci_w(int function, int reg, uint32_t data, uint32_t mem_mask)
{
if (ACCESSING_BITS_24_31)
{
piix4_config_w(function, reg + 3, (data >> 24) & 0xff);
}
if (ACCESSING_BITS_16_23)
{
piix4_config_w(function, reg + 2, (data >> 16) & 0xff);
}
if (ACCESSING_BITS_8_15)
{
piix4_config_w(function, reg + 1, (data >> 8) & 0xff);
}
if (ACCESSING_BITS_0_7)
{
piix4_config_w(function, reg + 0, (data >> 0) & 0xff);
}
}
void xtom3d_state::isa_ram1_w(offs_t offset, uint32_t data, uint32_t mem_mask)
{
if (m_mtxc_config_reg[0x5a] & 0x2) // write to RAM if this region is write-enabled
{
COMBINE_DATA(m_isa_ram1.get() + offset);
}
}
void xtom3d_state::isa_ram2_w(offs_t offset, uint32_t data, uint32_t mem_mask)
{
if (m_mtxc_config_reg[0x5a] & 0x2) // write to RAM if this region is write-enabled
{
COMBINE_DATA(m_isa_ram2.get() + offset);
}
}
void xtom3d_state::bios_ext1_ram_w(offs_t offset, uint32_t data, uint32_t mem_mask)
{
if (m_mtxc_config_reg[0x5e] & 0x2) // write to RAM if this region is write-enabled
{
COMBINE_DATA(m_bios_ext1_ram.get() + offset);
}
}
void xtom3d_state::bios_ext2_ram_w(offs_t offset, uint32_t data, uint32_t mem_mask)
{
if (m_mtxc_config_reg[0x5e] & 0x20) // write to RAM if this region is write-enabled
{
COMBINE_DATA(m_bios_ext2_ram.get() + offset);
}
}
void xtom3d_state::bios_ext3_ram_w(offs_t offset, uint32_t data, uint32_t mem_mask)
{
if (m_mtxc_config_reg[0x5f] & 0x2) // write to RAM if this region is write-enabled
{
COMBINE_DATA(m_bios_ext3_ram.get() + offset);
}
}
void xtom3d_state::bios_ext4_ram_w(offs_t offset, uint32_t data, uint32_t mem_mask)
{
if (m_mtxc_config_reg[0x5f] & 0x20) // write to RAM if this region is write-enabled
{
COMBINE_DATA(m_bios_ext4_ram.get() + offset);
}
}
void xtom3d_state::bios_ram_w(offs_t offset, uint32_t data, uint32_t mem_mask)
{
if (m_mtxc_config_reg[0x59] & 0x20) // write to RAM if this region is write-enabled
{
COMBINE_DATA(m_bios_ram.get() + offset);
}
}
void xtom3d_state::xtom3d_map(address_map &map)
{
map(0x00000000, 0x0009ffff).ram();
map(0x000a0000, 0x000bffff).rw("vga", FUNC(vga_device::mem_r), FUNC(vga_device::mem_w));
map(0x000c0000, 0x000c3fff).bankr("video_bank1").w(FUNC(xtom3d_state::isa_ram1_w));
map(0x000c4000, 0x000c7fff).bankr("video_bank2").w(FUNC(xtom3d_state::isa_ram2_w));
map(0x000e0000, 0x000e3fff).bankr("bios_ext1").w(FUNC(xtom3d_state::bios_ext1_ram_w));
map(0x000e4000, 0x000e7fff).bankr("bios_ext2").w(FUNC(xtom3d_state::bios_ext2_ram_w));
map(0x000e8000, 0x000ebfff).bankr("bios_ext3").w(FUNC(xtom3d_state::bios_ext3_ram_w));
map(0x000ec000, 0x000effff).bankr("bios_ext4").w(FUNC(xtom3d_state::bios_ext4_ram_w));
map(0x000f0000, 0x000fffff).bankr("bios_bank").w(FUNC(xtom3d_state::bios_ram_w));
map(0x00100000, 0x01ffffff).ram();
map(0xfffe0000, 0xffffffff).rom().region("bios", 0); /* System BIOS */
map.unmap_value_high();
}
void xtom3d_state::xtom3d_io(address_map &map)
void xtom3d_isa_cards(device_slot_interface &device)
{
pcat32_io_common(map);
map(0x00e8, 0x00ef).noprw();
map(0x03b0, 0x03bf).rw("vga", FUNC(vga_device::port_03b0_r), FUNC(vga_device::port_03b0_w));
map(0x03c0, 0x03cf).rw("vga", FUNC(vga_device::port_03c0_r), FUNC(vga_device::port_03c0_w));
map(0x03d0, 0x03df).rw("vga", FUNC(vga_device::port_03d0_r), FUNC(vga_device::port_03d0_w));
map(0x0cf8, 0x0cff).rw("pcibus", FUNC(pci_bus_legacy_device::read), FUNC(pci_bus_legacy_device::write));
device.option_add_internal("oksan_romdisk", ISA16_OKSAN_ROM_DISK);
device.option_add_internal("oksan_lpc", ISA16_OKSAN_LPC);
}
void xtom3d_state::machine_start()
void xtom3d_state::romdisk_config(device_t *device)
{
m_bios_ram = std::make_unique<uint32_t[]>(0x10000/4);
m_bios_ext1_ram = std::make_unique<uint32_t[]>(0x4000/4);
m_bios_ext2_ram = std::make_unique<uint32_t[]>(0x4000/4);
m_bios_ext3_ram = std::make_unique<uint32_t[]>(0x4000/4);
m_bios_ext4_ram = std::make_unique<uint32_t[]>(0x4000/4);
m_isa_ram1 = std::make_unique<uint32_t[]>(0x4000/4);
m_isa_ram2 = std::make_unique<uint32_t[]>(0x4000/4);
for (int i = 0; i < 4; i++)
std::fill(std::begin(m_piix4_config_reg[i]), std::end(m_piix4_config_reg[i]), 0);
intel82439tx_init();
isa16_oksan_rom_disk &romdisk = *downcast<isa16_oksan_rom_disk *>(device);
romdisk.set_rom_tag("game_rom");
}
void xtom3d_state::machine_reset()
// TODO: stub for drive options (speed/drive type etc.)
/*void xtom3d_state::cdrom_config(device_t *device)
{
membank("bios_bank")->set_base(memregion("bios")->base() + 0x10000);
membank("bios_ext1")->set_base(memregion("bios")->base() + 0);
membank("bios_ext2")->set_base(memregion("bios")->base() + 0x4000);
membank("bios_ext3")->set_base(memregion("bios")->base() + 0x8000);
membank("bios_ext4")->set_base(memregion("bios")->base() + 0xc000);
membank("video_bank1")->set_base(memregion("video_bios")->base() + 0);
membank("video_bank2")->set_base(memregion("video_bios")->base() + 0x4000);
}
*/
// TODO: unverified PCI config space
void xtom3d_state::xtom3d(machine_config &config)
{
PENTIUM2(config, m_maincpu, 450000000/16); // actually Pentium II 450
PENTIUM2(config, m_maincpu, 450'000'000 / 16); // actually Pentium II 450
m_maincpu->set_addrmap(AS_PROGRAM, &xtom3d_state::xtom3d_map);
m_maincpu->set_addrmap(AS_IO, &xtom3d_state::xtom3d_io);
m_maincpu->set_irq_acknowledge_callback("pic8259_1", FUNC(pic8259_device::inta_cb));
// m_maincpu->set_addrmap(AS_IO, &xtom3d_state::xtom3d_io);
m_maincpu->set_irq_acknowledge_callback("pci:07.0:pic8259_master", FUNC(pic8259_device::inta_cb));
m_maincpu->smiact().set("pci:00.0", FUNC(i82443bx_host_device::smi_act_w));
pcat_common(config);
PCI_ROOT(config, "pci", 0);
// PCB has ZX marking but BIOS returns BX, shouldn't matter
I82443BX_HOST(config, "pci:00.0", 0, "maincpu", 32*1024*1024);
I82443BX_BRIDGE(config, "pci:01.0", 0 ); //"pci:01.0:00.0");
//I82443BX_AGP (config, "pci:01.0:00.0");
PCI_BUS_LEGACY(config, m_pcibus, 0, 0);
m_pcibus->set_device(0, FUNC(xtom3d_state::intel82439tx_pci_r), FUNC(xtom3d_state::intel82439tx_pci_w));
m_pcibus->set_device(7, FUNC(xtom3d_state::intel82371ab_pci_r), FUNC(xtom3d_state::intel82371ab_pci_w));
i82371eb_isa_device &isa(I82371EB_ISA(config, "pci:07.0", 0, m_maincpu));
isa.boot_state_hook().set([](u8 data) { /* printf("%02x\n", data); */ });
isa.smi().set_inputline("maincpu", INPUT_LINE_SMI);
/* video hardware */
pcvideo_vga(config);
i82371eb_ide_device &ide(I82371EB_IDE(config, PCI_IDE_ID, 0, m_maincpu));
ide.irq_pri().set("pci:07.0", FUNC(i82371eb_isa_device::pc_irq14_w));
ide.irq_sec().set("pci:07.0", FUNC(i82371eb_isa_device::pc_mirq0_w));
ide.subdevice<bus_master_ide_controller_device>("ide1")->slot(0).set_default_option("cdrom");
// ide.subdevice<bus_master_ide_controller_device>("ide1")->slot(0).set_fixed(true);
ide.subdevice<bus_master_ide_controller_device>("ide2")->slot(0).set_default_option(nullptr);
I82371EB_USB (config, "pci:07.2", 0);
I82371EB_ACPI(config, "pci:07.3", 0);
LPC_ACPI (config, "pci:07.3:acpi", 0);
SMBUS (config, "pci:07.3:smbus", 0);
ISA16_SLOT(config, "board1", 0, "pci:07.0:isabus", xtom3d_isa_cards, "oksan_romdisk", true).set_option_machine_config("oksan_romdisk", romdisk_config);
ISA16_SLOT(config, "board2", 0, "pci:07.0:isabus", xtom3d_isa_cards, "oksan_lpc", true);
// TODO: another ISA slot for sound system + EEPROM
ISA16_SLOT(config, "isa1", 0, "pci:07.0:isabus", pc_isa16_cards, nullptr, false);
ISA16_SLOT(config, "isa2", 0, "pci:07.0:isabus", pc_isa16_cards, nullptr, false);
// Expansion slots, mapping SVGA for debugging
#if ENABLE_VOODOO
VOODOO_BANSHEE_PCI(config, m_voodoo, 0, m_maincpu, "screen"); // "pci:0d.0" J4D2
// TODO: confirm values
m_voodoo->set_fbmem(2);
m_voodoo->set_tmumem(4, 4);
m_voodoo->set_status_cycles(1000);
//subdevice<generic_voodoo_device>(PCI_AGP_ID":voodoo")->vblank_callback().set(FUNC(xtom3d_state::vblank_assert));
// TODO: fix legacy raw setup here
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(57);
screen.set_size(640, 480);
screen.set_visarea(0, 640 - 1, 0, 480 - 1);
screen.set_screen_update(PCI_AGP_ID, FUNC(voodoo_banshee_pci_device::screen_update));
#else
VIRGE_PCI(config, "pci:0e.0", 0); // J4C1
#endif
// "pci:0d.0" J4D2
// "pci:0e.0" J4D1
}
ROM_START( xtom3d )
ROM_REGION32_LE(0x20000, "bios", 0)
ROM_REGION32_LE(0x20000, "pci:07.0", 0)
ROM_LOAD( "bios.u22", 0x000000, 0x020000, CRC(f7c58044) SHA1(fd967d009e0d3c8ed9dd7be852946f2b9dee7671) )
ROM_REGION( 0x8000, "video_bios", 0 ) // TODO: no VGA card is hooked up, to be removed
ROM_LOAD16_BYTE( "trident_tgui9680_bios.bin", 0x0000, 0x4000, BAD_DUMP CRC(1eebde64) SHA1(67896a854d43a575037613b3506aea6dae5d6a19) )
ROM_CONTINUE( 0x0001, 0x4000 )
ROM_REGION(0xe00000, "user2", 0)
ROM_REGION32_LE(0x1000000, "board1:game_rom", ROMREGION_ERASEFF )
ROM_LOAD( "u3", 0x000000, 0x200000, CRC(f332e030) SHA1(f04fc7fc97e6ada8122ea7d111455043d7cc42df) )
ROM_LOAD( "u4", 0x200000, 0x200000, CRC(ac40ea0b) SHA1(6fcb86f493885d62d20df6bddaa1a1b19d478c65) )
ROM_LOAD( "u5", 0x400000, 0x200000, CRC(0fb98a20) SHA1(d21f33b0ca65dc6f90a411a9682f960e9c60244c) )
ROM_LOAD( "u6", 0x600000, 0x200000, CRC(5c092c58) SHA1(d347e1ed957cc989dc71f4f347af926589ae926d) )
ROM_LOAD( "u7", 0x800000, 0x200000, CRC(833c179c) SHA1(586555f5a4066a762fc05a43ef01be9fa202bb7f) )
ROM_LOAD( "u19", 0xa00000, 0x200000, CRC(a1ae73d0) SHA1(232c73bfee426b5f651a015c505c26b8ed7176b7) )
ROM_LOAD( "u20", 0xc00000, 0x200000, CRC(452131d9) SHA1(f62a0f1a7da9025ac1f7d5de4df90166871ac1e5) )
ROM_REGION(0x400000, "board3:sound_rom", ROMREGION_ERASEFF )
ROM_LOAD( "u19", 0x000000, 0x200000, CRC(a1ae73d0) SHA1(232c73bfee426b5f651a015c505c26b8ed7176b7) )
ROM_LOAD( "u20", 0x200000, 0x200000, CRC(452131d9) SHA1(f62a0f1a7da9025ac1f7d5de4df90166871ac1e5) )
ROM_END
} // Anonymous namespace
// provided dump is half size and definitely don't seem sane,
// just assume they didn't change that part
// ROM_LOAD( "bios.u22", 0x000000, 0x010000, BAD_DUMP CRC(574bb327) SHA1(c24484e9b304b9d570c5ead6be768f563d5c389f) )
#define PUMPITUP_BIOS \
ROM_REGION32_LE(0x20000, "pci:07.0", 0) \
ROM_LOAD( "bios.u22", 0x000000, 0x020000, CRC(f7c58044) SHA1(fd967d009e0d3c8ed9dd7be852946f2b9dee7671) ) \
ROM_REGION32_LE(0x1000000, "board1:game_rom", ROMREGION_ERASEFF ) \
ROM_LOAD( "piu10.u8", 0x000000, 0x200000, CRC(5911e31a) SHA1(295723b9b7da9e55b5dd5586b23b06355f4837ef) ) \
ROM_REGION(0x400000, "board3:sound_rom", ROMREGION_ERASEFF ) \
ROM_LOAD( "piu10.u9", 0x000000, 0x200000, CRC(9c436cfa) SHA1(480ea52e74721d1963ced41be5c482b7b913ccd2) )
GAME(1999, xtom3d, 0, xtom3d, 0, xtom3d_state, empty_init, ROT0, "Jamie System Development", "X Tom 3D", MACHINE_IS_SKELETON)
ROM_START( pumpitup )
PUMPITUP_BIOS
ROM_END
ROM_START( pumpit1 )
PUMPITUP_BIOS
DISK_REGION( PCI_IDE_ID":ide1:0:cdrom" )
DISK_IMAGE_READONLY( "19990930", 0, SHA1(a848061806c56ba30c75a24233300f175fb3eb9d) )
ROM_END
} // anonymous namespace
GAME(1999, xtom3d, 0, xtom3d, 0, xtom3d_state, empty_init, ROT0, "Andamiro / Jamie System Development", "X Tom 3D", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
GAME(1999, pumpitup, 0, xtom3d, 0, xtom3d_state, empty_init, ROT0, "Andamiro", "Pump It Up BIOS", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_IS_BIOS_ROOT )
GAME(1999, pumpit1, pumpitup, xtom3d, 0, xtom3d_state, empty_init, ROT0, "Andamiro", "Pump It Up: The 1st Dance Floor", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
//GAME(1999, pumpit2, pumpitup, xtom3d, 0, xtom3d_state, empty_init, ROT0, "Andamiro", "Pump it Up: The 2nd Dance Floor", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
//GAME(1999, pumpit3, pumpitup, xtom3d, 0, xtom3d_state, empty_init, ROT0, "Andamiro", "Pump it Up The O.B.G: The 3rd Dance Floor", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
// GAME(2000, pumpito, pumpitup, xtom3d, 0, xtom3d_state, empty_init, ROT0, "Andamiro", "Pump it Up The O.B.G: The Season Evolution Dance Floor", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
// GAME(2000, pumpitc, pumpitup, xtom3d, 0, xtom3d_state, empty_init, ROT0, "Andamiro", "Pump it Up: The Collection", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
// GAME(2000, pumpitpc, pumpitup, xtom3d, 0, xtom3d_state, empty_init, ROT0, "Andamiro", "Pump it Up: The Perfect Collection", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
// GAME(2001, pumpite, pumpitup, xtom3d, 0, xtom3d_state, empty_init, ROT0, "Andamiro", "Pump it Up Extra", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
// GAME(2001, pumpitpr, pumpitup, xtom3d, 0, xtom3d_state, empty_init, ROT0, "Andamiro","Pump it Up The Premiere: The International Dance Floor", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
// GAME(2001, pumpitpx, pumpitup, xtom3d, 0, xtom3d_state, empty_init, ROT0, "Andamiro", "Pump it Up The PREX: The International Dance Floor", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
// GAME(2002, pumpit8, pumpitup, xtom3d, 0, xtom3d_state, empty_init, ROT0, "Andamiro", "Pump it Up The Rebirth: The 8th Dance Floor", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
// GAME(2002, pumpitp2, pumpitup, xtom3d, 0, xtom3d_state, empty_init, ROT0, "Andamiro", "Pump it Up The Premiere 2: The International 2nd Dance Floor", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
// GAME(2002, pumpipx2, pumpitup, xtom3d, 0, xtom3d_state, empty_init, ROT0, "Andamiro", "Pump it Up The PREX 2", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
// GAME(2003, pumpitp3, pumpitup, xtom3d, 0, xtom3d_state, empty_init, ROT0, "Andamiro", "Pump it Up The Premiere 3: The International 3rd Dance Floor", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
// GAME(2003, pumpipx3, pumpitup, xtom3d, 0, xtom3d_state, empty_init, ROT0, "Andamiro", "Pump it Up The PREX 3: The International 4th Dance Floor", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
// GAME(1999, "family production,inc", "N3 Heartbreakers Advanced" known to exist on this HW
// https://namu.wiki/w/%ED%95%98%ED%8A%B8%20%EB%B8%8C%EB%A0%88%EC%9D%B4%EC%BB%A4%EC%A6%88
// (Korean encoded URL)