summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine
diff options
context:
space:
mode:
author yz70s <yz70s@users.noreply.github.com>2018-06-11 15:42:55 +0200
committer yz70s <yz70s@users.noreply.github.com>2018-06-11 15:53:45 +0200
commita89cd327d9117aecadf7b19c79cf078cba64d34e (patch)
tree2786666b01b721d00556d9a153e2b52215aee2cd /src/devices/machine
parent529ddf11fae5d96d6956e65dcb12b6e1243e623a (diff)
pcipc.cpp: first partially working implemantetion with isa, superio and et4000 (nw)
Video shows bios messages and is possible to go into bios configuration screens. i82371sb.cpp has isa enabled and a new device for the pci ide controller. There are still a few things to correct here and there but i think it's a nice starting point.
Diffstat (limited to 'src/devices/machine')
-rw-r--r--src/devices/machine/i82371sb.cpp233
-rw-r--r--src/devices/machine/i82371sb.h72
2 files changed, 277 insertions, 28 deletions
diff --git a/src/devices/machine/i82371sb.cpp b/src/devices/machine/i82371sb.cpp
index 0715117c997..d37f87b8b46 100644
--- a/src/devices/machine/i82371sb.cpp
+++ b/src/devices/machine/i82371sb.cpp
@@ -32,10 +32,11 @@ void i82371sb_isa_device::config_map(address_map &map)
void i82371sb_isa_device::internal_io_map(address_map &map)
{
+ map(0x0000, 0xffff).rw(m_isabus, FUNC(isa16_device::io16_r), FUNC(isa16_device::io16_w));
map(0x0000, 0x001f).rw("dma8237_1", FUNC(am9517a_device::read), FUNC(am9517a_device::write));
map(0x0020, 0x003f).rw("pic8259_master", FUNC(pic8259_device::read), FUNC(pic8259_device::write));
map(0x0040, 0x005f).rw("pit8254", FUNC(pit8254_device::read), FUNC(pit8254_device::write));
- map(0x0061, 0x0061).rw(FUNC(i82371sb_isa_device::at_portb_r), FUNC(i82371sb_isa_device::at_portb_w));
+ map(0x0060, 0x0061).rw(FUNC(i82371sb_isa_device::at_portb_r), FUNC(i82371sb_isa_device::at_portb_w));
map(0x0080, 0x009f).rw(FUNC(i82371sb_isa_device::at_page8_r), FUNC(i82371sb_isa_device::at_page8_w));
map(0x00a0, 0x00bf).rw("pic8259_slave", FUNC(pic8259_device::read), FUNC(pic8259_device::write));
map(0x00b2, 0x00b3).rw(FUNC(i82371sb_isa_device::read_apmcapms), FUNC(i82371sb_isa_device::write_apmcapms));
@@ -98,14 +99,6 @@ MACHINE_CONFIG_START(i82371sb_isa_device::device_add_mconfig)
MCFG_PIC8259_OUT_INT_CB(WRITELINE("pic8259_master", pic8259_device, ir2_w))
MCFG_PIC8259_IN_SP_CB(GND)
-// MCFG_BUS_MASTER_IDE_CONTROLLER_ADD("ide", ata_devices, "hdd", nullptr, false)
-// MCFG_ATA_INTERFACE_IRQ_HANDLER(WRITELINE("pic8259_slave", pic8259_device, ir6_w))
-// MCFG_BUS_MASTER_IDE_CONTROLLER_SPACE(":maincpu", AS_PROGRAM)
-//
-// MCFG_BUS_MASTER_IDE_CONTROLLER_ADD("ide2", ata_devices, "cdrom", nullptr, false)
-// MCFG_ATA_INTERFACE_IRQ_HANDLER(WRITELINE("pic8259_slave", pic8259_device, ir7_w))
-// MCFG_BUS_MASTER_IDE_CONTROLLER_SPACE(":maincpu", AS_PROGRAM)
-
/* sound hardware */
SPEAKER(config, "mono").front_center();
MCFG_DEVICE_ADD("speaker", SPEAKER_SOUND, 0)
@@ -183,15 +176,12 @@ void i82371sb_isa_device::device_reset()
ctlmtr = 0x00;
cthmtr = 0x00;
-
-
m_at_spkrdata = 0;
m_pit_out2 = 1;
m_dma_channel = -1;
m_cur_eop = false;
m_nmi_enabled = 0;
m_refresh = false;
-
}
void i82371sb_isa_device::reset_all_mappings()
@@ -396,13 +386,12 @@ void i82371sb_isa_device::map_bios(address_space *memory_space, uint32_t start,
void i82371sb_isa_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_readwrite_handler(0, 0xffff, read16_delegate(FUNC(isa16_device::io16_r), &(*m_isabus)), write16_delegate(FUNC(isa16_device::io16_w), &(*m_isabus)));
memory_space->install_readwrite_handler(0, 0xfffff, read16_delegate(FUNC(isa16_device::mem16_r), &(*m_isabus)), write16_delegate(FUNC(isa16_device::mem16_w), &(*m_isabus)));
// assume that map_extra of the southbridge is called before the one of the northbridge
map_bios(memory_space, 0xfffc0000, 0xffffffff);
map_bios(memory_space, 0x000e0000, 0x000fffff);
- io_space->install_device(0, 0xff, *this, &i82371sb_isa_device::internal_io_map);
+ io_space->install_device(0, 0xffff, *this, &i82371sb_isa_device::internal_io_map);
#if 0
if(fwh_dec_en1 & 0x80) {
@@ -681,27 +670,41 @@ WRITE_LINE_MEMBER( i82371sb_isa_device::pc_dack7_w ) { pc_select_dma_channel(7,
READ8_MEMBER( i82371sb_isa_device::at_portb_r )
{
- uint8_t data = m_at_speaker;
- data &= ~0xd0; /* AT BIOS don't likes this being set */
+ if (offset == 0)
+ {
+ return m_isabus->io16_r(space, 0x60 / 2, 0x00ff);
+ }
+ else
+ {
+ uint8_t data = m_at_speaker;
+ 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;
+ /* 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)
- data |= 0x20;
- else
- data &= ~0x20; /* ps2m30 wants this */
+ if (m_pit_out2)
+ data |= 0x20;
+ else
+ data &= ~0x20; /* ps2m30 wants this */
- return data;
+ return data;
+ }
}
WRITE8_MEMBER( i82371sb_isa_device::at_portb_w )
{
- m_at_speaker = data;
- m_pit8254->write_gate2(BIT(data, 0));
- at_speaker_set_spkrdata( BIT(data, 1));
- m_channel_check = BIT(data, 3);
- m_isabus->set_nmi_state((m_nmi_enabled==0) && (m_channel_check==0));
+ if (offset == 0)
+ {
+ m_isabus->io16_w(space, 0x60 / 2, data, 0x00ff);
+ }
+ else
+ {
+ m_at_speaker = data;
+ m_pit8254->write_gate2(BIT(data, 0));
+ at_speaker_set_spkrdata( BIT(data, 1));
+ m_channel_check = BIT(data, 3);
+ m_isabus->set_nmi_state((m_nmi_enabled==0) && (m_channel_check==0));
+ }
}
READ8_MEMBER( i82371sb_isa_device::at_dma8237_2_r )
@@ -747,3 +750,177 @@ void i82371sb_isa_device::update_smireq_line()
else
m_smi_callback(0);
}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////
+
+DEFINE_DEVICE_TYPE(I82371SB_IDE, i82371sb_ide_device, "i82371sb_ide", "Intel 82371 southbridge IDE interface")
+
+void i82371sb_ide_device::config_map(address_map &map)
+{
+ map(0x04, 0x05).rw(FUNC(i82371sb_ide_device::command_r), FUNC(i82371sb_ide_device::command_w));
+ map(0x20, 0x23).rw(FUNC(i82371sb_ide_device::bmiba_r), FUNC(i82371sb_ide_device::bmiba_w));
+ map(0x40, 0x41).rw(FUNC(i82371sb_ide_device::idetim_primary_r), FUNC(i82371sb_ide_device::idetim_primary_w));
+ map(0x42, 0x43).rw(FUNC(i82371sb_ide_device::idetim_secondary_r), FUNC(i82371sb_ide_device::idetim_secondary_w));
+ map(0x44, 0x44).rw(FUNC(i82371sb_ide_device::sidetim_r), FUNC(i82371sb_ide_device::sidetim_w));
+}
+
+void i82371sb_ide_device::internal_io_map(address_map &map)
+{
+ map(0x0170, 0x0177).rw(FUNC(i82371sb_ide_device::ide2_read32_cs0_r), FUNC(i82371sb_ide_device::ide2_write32_cs0_w));
+ map(0x01f0, 0x01f7).rw(FUNC(i82371sb_ide_device::ide1_read32_cs0_r), FUNC(i82371sb_ide_device::ide1_write32_cs0_w));
+ map(0x0376, 0x0376).rw(FUNC(i82371sb_ide_device::ide2_read_cs1_r), FUNC(i82371sb_ide_device::ide2_write_cs1_w));
+ map(0x03f6, 0x03f6).rw(FUNC(i82371sb_ide_device::ide1_read_cs1_r), FUNC(i82371sb_ide_device::ide1_write_cs1_w));
+}
+
+MACHINE_CONFIG_START(i82371sb_ide_device::device_add_mconfig)
+ MCFG_BUS_MASTER_IDE_CONTROLLER_ADD("ide1", ata_devices, "hdd", nullptr, false)
+ MCFG_ATA_INTERFACE_IRQ_HANDLER(WRITELINE(*this, i82371sb_ide_device, primary_int))
+ MCFG_BUS_MASTER_IDE_CONTROLLER_SPACE(":maincpu", AS_PROGRAM)
+
+ MCFG_BUS_MASTER_IDE_CONTROLLER_ADD("ide2", ata_devices, "cdrom", nullptr, false)
+ MCFG_ATA_INTERFACE_IRQ_HANDLER(WRITELINE(*this, i82371sb_ide_device, secondary_int))
+ MCFG_BUS_MASTER_IDE_CONTROLLER_SPACE(":maincpu", AS_PROGRAM)
+MACHINE_CONFIG_END
+
+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)
+ , command(2)
+ , bmiba(1)
+ , idetim_primary(0)
+ , idetim_secondary(0)
+ , sidetim(0)
+ , m_irq_pri_callback(*this)
+ , m_irq_sec_callback(*this)
+ , m_ide1(*this, "ide1")
+ , m_ide2(*this, "ide2")
+{
+ set_ids(0x80867010, 0x03, 0x010180, 0x00000000);
+}
+
+void i82371sb_ide_device::device_start()
+{
+}
+
+void i82371sb_ide_device::device_reset()
+{
+}
+
+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)
+{
+ if (command & 1)
+ {
+ offs_t m_base = bmiba & 0xfff0;
+
+ io_space->install_device(0, 0x3ff, *this, &i82371sb_ide_device::internal_io_map);
+ io_space->install_readwrite_handler(m_base, m_base + 0x7, read32_delegate(FUNC(bus_master_ide_controller_device::bmdma_r), &(*m_ide1)), write32_delegate(FUNC(bus_master_ide_controller_device::bmdma_w), &(*m_ide1)), 0xffffffff);
+ io_space->install_readwrite_handler(m_base + 0x8, m_base + 0xf, read32_delegate(FUNC(bus_master_ide_controller_device::bmdma_r), &(*m_ide2)), write32_delegate(FUNC(bus_master_ide_controller_device::bmdma_w), &(*m_ide2)), 0xffffffff);
+ }
+}
+
+WRITE_LINE_MEMBER(i82371sb_ide_device::primary_int)
+{
+ m_irq_pri_callback(state);
+}
+
+WRITE_LINE_MEMBER(i82371sb_ide_device::secondary_int)
+{
+ m_irq_sec_callback(state);
+}
+
+READ16_MEMBER(i82371sb_ide_device::command_r)
+{
+ return command;
+}
+
+WRITE16_MEMBER(i82371sb_ide_device::command_w)
+{
+ mem_mask &= 5;
+ COMBINE_DATA(&command);
+ if (mem_mask & 1)
+ remap_cb();
+}
+
+READ32_MEMBER(i82371sb_ide_device::bmiba_r)
+{
+ return bmiba;
+}
+
+WRITE32_MEMBER(i82371sb_ide_device::bmiba_w)
+{
+ mem_mask &= 0xfff0;
+ COMBINE_DATA(&bmiba);
+ if (command & 1)
+ remap_cb();
+}
+
+READ16_MEMBER(i82371sb_ide_device::idetim_primary_r)
+{
+ return idetim_primary;
+}
+
+WRITE16_MEMBER(i82371sb_ide_device::idetim_primary_w)
+{
+}
+
+READ16_MEMBER(i82371sb_ide_device::idetim_secondary_r)
+{
+ return idetim_secondary;
+}
+
+WRITE16_MEMBER(i82371sb_ide_device::idetim_secondary_w)
+{
+}
+
+READ8_MEMBER(i82371sb_ide_device::sidetim_r)
+{
+ return sidetim;
+}
+
+WRITE8_MEMBER(i82371sb_ide_device::sidetim_w)
+{
+}
+
+READ32_MEMBER(i82371sb_ide_device::ide1_read32_cs0_r)
+{
+ return m_ide1->read_cs0(offset, mem_mask);
+}
+
+WRITE32_MEMBER(i82371sb_ide_device::ide1_write32_cs0_w)
+{
+ m_ide1->write_cs0(offset, data, mem_mask);
+}
+
+READ32_MEMBER(i82371sb_ide_device::ide2_read32_cs0_r)
+{
+ return m_ide2->read_cs0(offset, mem_mask);
+}
+
+WRITE32_MEMBER(i82371sb_ide_device::ide2_write32_cs0_w)
+{
+ m_ide2->write_cs0(offset, data, mem_mask);
+}
+
+READ8_MEMBER(i82371sb_ide_device::ide1_read_cs1_r)
+{
+ return m_ide1->read_cs1(1, 0xff0000) >> 16;
+}
+
+WRITE8_MEMBER(i82371sb_ide_device::ide1_write_cs1_w)
+{
+ m_ide1->write_cs1(1, data << 16, 0xff0000);
+}
+
+READ8_MEMBER(i82371sb_ide_device::ide2_read_cs1_r)
+{
+ return m_ide2->read_cs1(1, 0xff0000) >> 16;
+}
+
+WRITE8_MEMBER(i82371sb_ide_device::ide2_write_cs1_w)
+{
+ m_ide2->write_cs1(1, data << 16, 0xff0000);
+}
diff --git a/src/devices/machine/i82371sb.h b/src/devices/machine/i82371sb.h
index 1c6a4582167..96134a3c6a8 100644
--- a/src/devices/machine/i82371sb.h
+++ b/src/devices/machine/i82371sb.h
@@ -7,6 +7,7 @@
#pragma once
#include "pci.h"
+#include "machine/pci-ide.h"
#include "machine/ins8250.h"
#include "machine/ds128x.h"
@@ -180,4 +181,75 @@ private:
DECLARE_DEVICE_TYPE(I82371SB_ISA, i82371sb_isa_device)
+/////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define MCFG_I82371SB_IDE_IRQ_PRI_CB(_devcb) \
+ devcb = &downcast<i82371sb_ide_device &>(*device).set_irq_pri_callback(DEVCB_##_devcb);
+
+#define MCFG_I82371SB_IDE_IRQ_SEC_CB(_devcb) \
+ devcb = &downcast<i82371sb_ide_device &>(*device).set_irq_sec_callback(DEVCB_##_devcb);
+
+#define MCFG_I82371SB_IDE_INTERRUPTS(_tag, _dev, _irq_pri, _irq_sec) \
+ MCFG_I82371SB_IDE_IRQ_PRI_CB(WRITELINE(_tag, _dev, _irq_pri)) \
+ MCFG_I82371SB_IDE_IRQ_SEC_CB(WRITELINE(_tag, _dev, _irq_sec))
+
+class i82371sb_ide_device : public pci_device {
+public:
+ i82371sb_ide_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ template <class Object> devcb_base &set_irq_pri_callback(Object &&cb) { return m_irq_pri_callback.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_irq_sec_callback(Object &&cb) { return m_irq_sec_callback.set_callback(std::forward<Object>(cb)); }
+
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ // optional information overrides
+ 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;
+
+ DECLARE_WRITE_LINE_MEMBER(primary_int);
+ DECLARE_WRITE_LINE_MEMBER(secondary_int);
+
+private:
+ DECLARE_READ16_MEMBER(command_r);
+ DECLARE_WRITE16_MEMBER(command_w);
+ DECLARE_READ32_MEMBER(bmiba_r);
+ DECLARE_WRITE32_MEMBER(bmiba_w);
+ DECLARE_READ16_MEMBER(idetim_primary_r);
+ DECLARE_WRITE16_MEMBER(idetim_primary_w);
+ DECLARE_READ16_MEMBER(idetim_secondary_r);
+ DECLARE_WRITE16_MEMBER(idetim_secondary_w);
+ DECLARE_READ8_MEMBER(sidetim_r);
+ DECLARE_WRITE8_MEMBER(sidetim_w);
+
+ DECLARE_READ32_MEMBER(ide1_read32_cs0_r);
+ DECLARE_WRITE32_MEMBER(ide1_write32_cs0_w);
+ DECLARE_READ32_MEMBER(ide2_read32_cs0_r);
+ DECLARE_WRITE32_MEMBER(ide2_write32_cs0_w);
+ DECLARE_READ8_MEMBER(ide1_read_cs1_r);
+ DECLARE_WRITE8_MEMBER(ide1_write_cs1_w);
+ DECLARE_READ8_MEMBER(ide2_read_cs1_r);
+ DECLARE_WRITE8_MEMBER(ide2_write_cs1_w);
+
+ void internal_io_map(address_map &map);
+
+ uint16_t command;
+ uint32_t bmiba;
+ int idetim_primary, idetim_secondary;
+ int sidetim;
+
+ devcb_write_line m_irq_pri_callback;
+ devcb_write_line m_irq_sec_callback;
+
+ required_device<bus_master_ide_controller_device> m_ide1;
+ required_device<bus_master_ide_controller_device> m_ide2;
+};
+
+DECLARE_DEVICE_TYPE(I82371SB_IDE, i82371sb_ide_device)
+
#endif // MAME_MACHINE_I82371SB_H