From 876f0bb0b3a53b3e9050c1b20737ee69766915c1 Mon Sep 17 00:00:00 2001 From: arbee Date: Mon, 5 Jun 2017 22:26:49 -0400 Subject: Initial support for SiS85c496/497 PCI chipset. [R. Belmont] --- scripts/src/machine.lua | 2 + src/devices/machine/sis85c496.cpp | 578 ++++++++++++++++++++++++++++++++++++++ src/devices/machine/sis85c496.h | 153 ++++++++++ src/mame/drivers/mtouchxl.cpp | 42 ++- 4 files changed, 769 insertions(+), 6 deletions(-) create mode 100644 src/devices/machine/sis85c496.cpp create mode 100644 src/devices/machine/sis85c496.h diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua index e52bb8e43bb..93a51243c1b 100644 --- a/scripts/src/machine.lua +++ b/scripts/src/machine.lua @@ -2008,6 +2008,8 @@ if (MACHINES["PCI"]~=null) then MAME_DIR .. "src/devices/machine/vrc5074.h", MAME_DIR .. "src/devices/machine/gt64xxx.cpp", MAME_DIR .. "src/devices/machine/gt64xxx.h", + MAME_DIR .. "src/devices/machine/sis85c496.cpp", + MAME_DIR .. "src/devices/machine/sis85c496.h", } end diff --git a/src/devices/machine/sis85c496.cpp b/src/devices/machine/sis85c496.cpp new file mode 100644 index 00000000000..0cc9d0c8dfd --- /dev/null +++ b/src/devices/machine/sis85c496.cpp @@ -0,0 +1,578 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont, O. Galibert +/*************************************************************************** + + sis85c496.cpp - SiS 85C496/497 PCI chipset + by R. Belmont (based on i82439hx.cpp/i82439tx.cpp by O. Galibert) + + Unlike Intel chipsets, the southbridge is not a PCI device; + it connects via a proprietary bus to the northbridge, and the two + chips appear to software/the BIOS as a single chip. Thus we emulate + them in a single file. + +***************************************************************************/ + +#include "emu.h" +#include "sis85c496.h" +#include "bus/pc_kbd/keyboards.h" +#include "speaker.h" + +DEFINE_DEVICE_TYPE(SIS85C496, sis85c496_host_device, "sis85c496", "SiS 85C496/497 chipset") + +DEVICE_ADDRESS_MAP_START(config_map, 32, sis85c496_host_device) + AM_RANGE(0x40, 0x43) AM_READWRITE8(dram_config_r, dram_config_w, 0x000000ff) + AM_RANGE(0x44, 0x47) AM_READWRITE16(shadow_config_r, shadow_config_w, 0x0000ffff) + AM_RANGE(0xc8, 0xcb) AM_READWRITE(mailbox_r, mailbox_w) + AM_RANGE(0xd0, 0xd3) AM_READWRITE8(bios_config_r, bios_config_w, 0x000000ff) + AM_RANGE(0xd0, 0xd3) AM_READWRITE8(isa_decoder_r, isa_decoder_w, 0x0000ff00) + + AM_INHERIT_FROM(pci_host_device::config_map) +ADDRESS_MAP_END + +DEVICE_ADDRESS_MAP_START(internal_io_map, 32, sis85c496_host_device) + AM_RANGE(0x0000, 0x001f) AM_DEVREADWRITE8("dma8237_1", am9517a_device, read, write, 0xffffffff) + AM_RANGE(0x0020, 0x003f) AM_DEVREADWRITE8("pic8259_master", pic8259_device, read, write, 0xffffffff) + AM_RANGE(0x0040, 0x005f) AM_DEVREADWRITE8("pit8254", pit8254_device, read, write, 0xffffffff) + AM_RANGE(0x0060, 0x0063) AM_READWRITE8(at_keybc_r, at_keybc_w, 0xffffffff); + AM_RANGE(0x0064, 0x0067) AM_DEVREADWRITE8("keybc", at_keyboard_controller_device, status_r, command_w, 0xffffffff); + AM_RANGE(0x0070, 0x007f) AM_DEVREADWRITE8("rtc", ds12885_device, read, write, 0xffffffff); + AM_RANGE(0x0080, 0x009f) AM_READWRITE8(at_page8_r, at_page8_w, 0xffffffff); + AM_RANGE(0x00a0, 0x00bf) AM_DEVREADWRITE8("pic8259_slave", pic8259_device, read, write, 0xffffffff) + AM_RANGE(0x00c0, 0x00df) AM_READWRITE8(at_dma8237_2_r, at_dma8237_2_w, 0xffffffff); + AM_RANGE(0x00e0, 0x00ef) AM_NOP + + AM_INHERIT_FROM(pci_host_device::io_configuration_access_map) +ADDRESS_MAP_END + +MACHINE_CONFIG_MEMBER(sis85c496_host_device::device_add_mconfig) + MCFG_DEVICE_ADD("pit8254", PIT8254, 0) + MCFG_PIT8253_CLK0(4772720/4) /* heartbeat IRQ */ + MCFG_PIT8253_OUT0_HANDLER(WRITELINE(sis85c496_host_device, at_pit8254_out0_changed)) + MCFG_PIT8253_CLK1(4772720/4) /* dram refresh */ + MCFG_PIT8253_OUT1_HANDLER(WRITELINE(sis85c496_host_device, at_pit8254_out1_changed)) + MCFG_PIT8253_CLK2(4772720/4) /* pio port c pin 4, and speaker polling enough */ + MCFG_PIT8253_OUT2_HANDLER(WRITELINE(sis85c496_host_device, at_pit8254_out2_changed)) + + MCFG_DEVICE_ADD( "dma8237_1", AM9517A, XTAL_14_31818MHz/3 ) + MCFG_I8237_OUT_HREQ_CB(DEVWRITELINE("dma8237_2", am9517a_device, dreq0_w)) + MCFG_I8237_OUT_EOP_CB(WRITELINE(sis85c496_host_device, at_dma8237_out_eop)) + MCFG_I8237_IN_MEMR_CB(READ8(sis85c496_host_device, pc_dma_read_byte)) + MCFG_I8237_OUT_MEMW_CB(WRITE8(sis85c496_host_device, pc_dma_write_byte)) + MCFG_I8237_IN_IOR_0_CB(READ8(sis85c496_host_device, pc_dma8237_0_dack_r)) + MCFG_I8237_IN_IOR_1_CB(READ8(sis85c496_host_device, pc_dma8237_1_dack_r)) + MCFG_I8237_IN_IOR_2_CB(READ8(sis85c496_host_device, pc_dma8237_2_dack_r)) + MCFG_I8237_IN_IOR_3_CB(READ8(sis85c496_host_device, pc_dma8237_3_dack_r)) + MCFG_I8237_OUT_IOW_0_CB(WRITE8(sis85c496_host_device, pc_dma8237_0_dack_w)) + MCFG_I8237_OUT_IOW_1_CB(WRITE8(sis85c496_host_device, pc_dma8237_1_dack_w)) + MCFG_I8237_OUT_IOW_2_CB(WRITE8(sis85c496_host_device, pc_dma8237_2_dack_w)) + MCFG_I8237_OUT_IOW_3_CB(WRITE8(sis85c496_host_device, pc_dma8237_3_dack_w)) + MCFG_I8237_OUT_DACK_0_CB(WRITELINE(sis85c496_host_device, pc_dack0_w)) + MCFG_I8237_OUT_DACK_1_CB(WRITELINE(sis85c496_host_device, pc_dack1_w)) + MCFG_I8237_OUT_DACK_2_CB(WRITELINE(sis85c496_host_device, pc_dack2_w)) + MCFG_I8237_OUT_DACK_3_CB(WRITELINE(sis85c496_host_device, pc_dack3_w)) + + MCFG_DEVICE_ADD( "dma8237_2", AM9517A, XTAL_14_31818MHz/3 ) + MCFG_I8237_OUT_HREQ_CB(WRITELINE(sis85c496_host_device, pc_dma_hrq_changed)) + MCFG_I8237_IN_MEMR_CB(READ8(sis85c496_host_device, pc_dma_read_word)) + MCFG_I8237_OUT_MEMW_CB(WRITE8(sis85c496_host_device, pc_dma_write_word)) + MCFG_I8237_IN_IOR_1_CB(READ8(sis85c496_host_device, pc_dma8237_5_dack_r)) + MCFG_I8237_IN_IOR_2_CB(READ8(sis85c496_host_device, pc_dma8237_6_dack_r)) + MCFG_I8237_IN_IOR_3_CB(READ8(sis85c496_host_device, pc_dma8237_7_dack_r)) + MCFG_I8237_OUT_IOW_1_CB(WRITE8(sis85c496_host_device, pc_dma8237_5_dack_w)) + MCFG_I8237_OUT_IOW_2_CB(WRITE8(sis85c496_host_device, pc_dma8237_6_dack_w)) + MCFG_I8237_OUT_IOW_3_CB(WRITE8(sis85c496_host_device, pc_dma8237_7_dack_w)) + MCFG_I8237_OUT_DACK_0_CB(WRITELINE(sis85c496_host_device, pc_dack4_w)) + MCFG_I8237_OUT_DACK_1_CB(WRITELINE(sis85c496_host_device, pc_dack5_w)) + MCFG_I8237_OUT_DACK_2_CB(WRITELINE(sis85c496_host_device, pc_dack6_w)) + MCFG_I8237_OUT_DACK_3_CB(WRITELINE(sis85c496_host_device, pc_dack7_w)) + + MCFG_PIC8259_ADD( "pic8259_master", INPUTLINE(":maincpu", 0), VCC, READ8(sis85c496_host_device, get_slave_ack) ) + MCFG_PIC8259_ADD( "pic8259_slave", DEVWRITELINE("pic8259_master", pic8259_device, ir2_w), GND, NOOP) + + MCFG_DEVICE_ADD("keybc", AT_KEYBOARD_CONTROLLER, XTAL_12MHz) + MCFG_AT_KEYBOARD_CONTROLLER_SYSTEM_RESET_CB(INPUTLINE(":maincpu", INPUT_LINE_RESET)) + MCFG_AT_KEYBOARD_CONTROLLER_GATE_A20_CB(INPUTLINE(":maincpu", INPUT_LINE_A20)) + MCFG_AT_KEYBOARD_CONTROLLER_INPUT_BUFFER_FULL_CB(DEVWRITELINE("pic8259_master", pic8259_device, ir1_w)) + MCFG_AT_KEYBOARD_CONTROLLER_KEYBOARD_CLOCK_CB(DEVWRITELINE("pc_kbdc", pc_kbdc_device, clock_write_from_mb)) + MCFG_AT_KEYBOARD_CONTROLLER_KEYBOARD_DATA_CB(DEVWRITELINE("pc_kbdc", pc_kbdc_device, data_write_from_mb)) + MCFG_DEVICE_ADD("pc_kbdc", PC_KBDC, 0) + MCFG_PC_KBDC_OUT_CLOCK_CB(DEVWRITELINE("keybc", at_keyboard_controller_device, keyboard_clock_w)) + MCFG_PC_KBDC_OUT_DATA_CB(DEVWRITELINE("keybc", at_keyboard_controller_device, keyboard_data_w)) + MCFG_PC_KBDC_SLOT_ADD("pc_kbdc", "kbd", pc_at_keyboards, STR_KBD_MICROSOFT_NATURAL) + + MCFG_DS12885_ADD("rtc") + MCFG_MC146818_IRQ_HANDLER(DEVWRITELINE("pic8259_slave", pic8259_device, ir0_w)) + MCFG_MC146818_CENTURY_INDEX(0x32) + + /* sound hardware */ + MCFG_SPEAKER_STANDARD_MONO("mono") + MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) +MACHINE_CONFIG_END + + +sis85c496_host_device::sis85c496_host_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : pci_host_device(mconfig, SIS85C496, tag, owner, clock), + m_maincpu(*this, ":maincpu"), + 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_keybc(*this, "keybc"), + m_speaker(*this, "speaker"), + m_ds12885(*this, "rtc"), + m_pc_kbdc(*this, "pc_kbdc"), + m_at_spkrdata(0), m_pit_out2(0), m_dma_channel(0), m_cur_eop(false), m_dma_high_byte(0), m_at_speaker(0), m_refresh(false), m_channel_check(0), m_nmi_enabled(0) +{ +} + +void sis85c496_host_device::set_cpu_tag(const char *_cpu_tag) +{ + cpu_tag = _cpu_tag; +} + +void sis85c496_host_device::set_ram_size(int _ram_size) +{ + ram_size = _ram_size; +} + +void sis85c496_host_device::device_start() +{ + pci_host_device::device_start(); + + cpu = machine().device(cpu_tag); + memory_space = &cpu->space(AS_PROGRAM); + io_space = &cpu->space(AS_IO); + + memory_window_start = 0; + memory_window_end = 0xffffffff; + memory_offset = 0; + io_window_start = 0; + io_window_end = 0xffff; + io_offset = 0; + status = 0x0010; + + m_bios_config = 0x78; + m_dram_config = 0; + m_isa_decoder = 0xff; + m_shadctrl = 0; + + ram.resize(ram_size/4); +} + +void sis85c496_host_device::reset_all_mappings() +{ + pci_host_device::reset_all_mappings(); +} + +void sis85c496_host_device::device_reset() +{ + pci_host_device::device_reset(); + + m_at_spkrdata = 0; + m_pit_out2 = 1; + m_dma_channel = -1; + m_cur_eop = false; + m_nmi_enabled = 0; + m_refresh = false; +} + +void sis85c496_host_device::map_bios(address_space *memory_space, uint32_t start, uint32_t end) +{ + uint32_t mask = m_region->bytes() - 1; + memory_space->install_rom(start, end, m_region->base() + (start & mask)); +} + +void sis85c496_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) +{ + logerror("SiS496: mapping!\n"); + io_space->install_device(0, 0xffff, *this, &sis85c496_host_device::internal_io_map); + + if (m_bios_config & 0x40) + { + logerror("SiS496: BIOS at Exxxx\n"); + map_bios(memory_space, 0xfffe0000, 0xfffeffff); + + if ((m_shadctrl & 0x30) == 0) + { + map_bios(memory_space, 0x000e0000, 0x000effff); + } + else // at least one 32K block has shadow memory + { + if (m_shadctrl & 0x20) + { + logerror("Sis496: shadow RAM at e8000\n"); + memory_space->install_ram(0x000e8000, 0x000effff, &ram[0x000e8000/4]); + } + + if (m_shadctrl & 0x10) + { + logerror("Sis496: shadow RAM at e0000\n"); + memory_space->install_ram(0x000e0000, 0x000e7fff, &ram[0x000e0000/4]); + } + } + } + if (m_bios_config & 0x20) + { + logerror("SiS496: BIOS at Fxxxx\n"); + map_bios(memory_space, 0xffff0000, 0xffffffff); + + if ((m_shadctrl & 0xc0) == 0) + { + map_bios(memory_space, 0x000f0000, 0x000fffff); + } + else // at least one 32K block has shadow memory + { + if (m_shadctrl & 0x80) + { + logerror("Sis496: shadow RAM at f8000\n"); + memory_space->install_ram(0x000f8000, 0x000fffff, &ram[0x000f8000/4]); + } + + if (m_shadctrl & 0x40) + { + logerror("Sis496: shadow RAM at f0000\n"); + memory_space->install_ram(0x000f0000, 0x000f7fff, &ram[0x000f0000/4]); + } + } + } + + if (m_shadctrl & 0x08) + { + memory_space->install_ram(0x000d8000, 0x000dffff, &ram[0x000d8000/4]); + } + if (m_shadctrl & 0x04) + { + memory_space->install_ram(0x000d0000, 0x000d7fff, &ram[0x000d0000/4]); + } + if (m_shadctrl & 0x02) + { + memory_space->install_ram(0x000c8000, 0x000cffff, &ram[0x000c8000/4]); + } + if (m_shadctrl & 0x01) + { + memory_space->install_ram(0x000c0000, 0x000c7fff, &ram[0x000c0000/4]); + } + + if (m_isa_decoder & 0x01) + { + logerror("SiS496: ISA base 640K enabled\n"); + memory_space->install_ram(0x00000000, 0x0009ffff, &ram[0x00000000/4]); + } + + // 32 megs of RAM (todo: don't hardcode) + memory_space->install_ram(0x00100000, 0x01ffffff, &ram[0x00100000/4]); +} + +// Southbridge +READ8_MEMBER( sis85c496_host_device::get_slave_ack ) +{ + if (offset==2) // IRQ = 2 + return m_pic8259_slave->acknowledge(); + + return 0x00; +} + +void sis85c496_host_device::at_speaker_set_spkrdata(uint8_t data) +{ + m_at_spkrdata = data ? 1 : 0; + m_speaker->level_w(m_at_spkrdata & m_pit_out2); +} + + + +WRITE_LINE_MEMBER( sis85c496_host_device::at_pit8254_out0_changed ) +{ + if (m_pic8259_master) + m_pic8259_master->ir0_w(state); +} + +WRITE_LINE_MEMBER( sis85c496_host_device::at_pit8254_out1_changed ) +{ + if(state) + m_refresh = !m_refresh; +} + +WRITE_LINE_MEMBER( sis85c496_host_device::at_pit8254_out2_changed ) +{ + m_pit_out2 = state ? 1 : 0; + m_speaker->level_w(m_at_spkrdata & m_pit_out2); +} + +READ8_MEMBER( sis85c496_host_device::at_page8_r ) +{ + uint8_t data = m_at_pages[offset % 0x10]; + + switch(offset % 8) + { + case 1: + data = m_dma_offset[BIT(offset, 3)][2]; + break; + case 2: + data = m_dma_offset[BIT(offset, 3)][3]; + break; + case 3: + data = m_dma_offset[BIT(offset, 3)][1]; + break; + case 7: + data = m_dma_offset[BIT(offset, 3)][0]; + break; + } + return data; +} + + +WRITE8_MEMBER( sis85c496_host_device::at_page8_w ) +{ + m_at_pages[offset % 0x10] = data; + + switch(offset % 8) + { + case 0: + //m_boot_state_hook((offs_t)0, data); + break; + case 1: + m_dma_offset[BIT(offset, 3)][2] = data; + break; + case 2: + m_dma_offset[BIT(offset, 3)][3] = data; + break; + case 3: + m_dma_offset[BIT(offset, 3)][1] = data; + break; + case 7: + m_dma_offset[BIT(offset, 3)][0] = data; + break; + } +} + + +WRITE_LINE_MEMBER( sis85c496_host_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 ); +} + +READ8_MEMBER(sis85c496_host_device::pc_dma_read_byte) +{ + 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; + + result = prog_space.read_byte(page_offset + offset); + return result; +} + + +WRITE8_MEMBER(sis85c496_host_device::pc_dma_write_byte) +{ + 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; + + prog_space.write_byte(page_offset + offset, data); +} + + +READ8_MEMBER(sis85c496_host_device::pc_dma_read_word) +{ + 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; + + result = prog_space.read_word((page_offset & 0xfe0000) | (offset << 1)); + m_dma_high_byte = result & 0xFF00; + + return result & 0xFF; +} + + +WRITE8_MEMBER(sis85c496_host_device::pc_dma_write_word) +{ + 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; + + prog_space.write_word((page_offset & 0xfe0000) | (offset << 1), m_dma_high_byte | data); +} + + +READ8_MEMBER( sis85c496_host_device::pc_dma8237_0_dack_r ) { return 0; } //m_isabus->dack_r(0); } +READ8_MEMBER( sis85c496_host_device::pc_dma8237_1_dack_r ) { return 0; } //m_isabus->dack_r(1); } +READ8_MEMBER( sis85c496_host_device::pc_dma8237_2_dack_r ) { return 0; } //m_isabus->dack_r(2); } +READ8_MEMBER( sis85c496_host_device::pc_dma8237_3_dack_r ) { return 0; } //m_isabus->dack_r(3); } +READ8_MEMBER( sis85c496_host_device::pc_dma8237_5_dack_r ) { return 0; } //m_isabus->dack_r(5); } +READ8_MEMBER( sis85c496_host_device::pc_dma8237_6_dack_r ) { return 0; } //m_isabus->dack_r(6); } +READ8_MEMBER( sis85c496_host_device::pc_dma8237_7_dack_r ) { return 0; } //m_isabus->dack_r(7); } + + +WRITE8_MEMBER( sis85c496_host_device::pc_dma8237_0_dack_w ){ } //m_isabus->dack_w(0, data); } +WRITE8_MEMBER( sis85c496_host_device::pc_dma8237_1_dack_w ){ } //m_isabus->dack_w(1, data); } +WRITE8_MEMBER( sis85c496_host_device::pc_dma8237_2_dack_w ){ } //m_isabus->dack_w(2, data); } +WRITE8_MEMBER( sis85c496_host_device::pc_dma8237_3_dack_w ){ } //m_isabus->dack_w(3, data); } +WRITE8_MEMBER( sis85c496_host_device::pc_dma8237_5_dack_w ){ } //m_isabus->dack_w(5, data); } +WRITE8_MEMBER( sis85c496_host_device::pc_dma8237_6_dack_w ){ } //m_isabus->dack_w(6, data); } +WRITE8_MEMBER( sis85c496_host_device::pc_dma8237_7_dack_w ){ } //m_isabus->dack_w(7, data); } + +WRITE_LINE_MEMBER( sis85c496_host_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 ); +} + +void sis85c496_host_device::pc_select_dma_channel(int channel, bool state) +{ + if(!state) { + 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 ); + } +} + + +WRITE_LINE_MEMBER( sis85c496_host_device::pc_dack0_w ) { pc_select_dma_channel(0, state); } +WRITE_LINE_MEMBER( sis85c496_host_device::pc_dack1_w ) { pc_select_dma_channel(1, state); } +WRITE_LINE_MEMBER( sis85c496_host_device::pc_dack2_w ) { pc_select_dma_channel(2, state); } +WRITE_LINE_MEMBER( sis85c496_host_device::pc_dack3_w ) { pc_select_dma_channel(3, state); } +WRITE_LINE_MEMBER( sis85c496_host_device::pc_dack4_w ) { m_dma8237_1->hack_w( state ? 0 : 1); } // it's inverted +WRITE_LINE_MEMBER( sis85c496_host_device::pc_dack5_w ) { pc_select_dma_channel(5, state); } +WRITE_LINE_MEMBER( sis85c496_host_device::pc_dack6_w ) { pc_select_dma_channel(6, state); } +WRITE_LINE_MEMBER( sis85c496_host_device::pc_dack7_w ) { pc_select_dma_channel(7, state); } + +READ8_MEMBER( sis85c496_host_device::at_portb_r ) +{ + 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; + + if (m_pit_out2) + data |= 0x20; + else + data &= ~0x20; /* ps2m30 wants this */ + + return data; +} + +WRITE8_MEMBER( sis85c496_host_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)); +} + +READ8_MEMBER( sis85c496_host_device::at_dma8237_2_r ) +{ + return m_dma8237_2->read( space, offset / 2); +} + +WRITE8_MEMBER( sis85c496_host_device::at_dma8237_2_w ) +{ + m_dma8237_2->write( space, offset / 2, data); +} + +READ8_MEMBER( sis85c496_host_device::at_keybc_r ) +{ + switch (offset) + { + case 0: return m_keybc->data_r(space, 0); + case 1: return at_portb_r(space, 0); + } + + return 0xff; +} + +WRITE8_MEMBER( sis85c496_host_device::at_keybc_w ) +{ + switch (offset) + { + case 0: m_keybc->data_w(space, 0, data); break; + case 1: at_portb_w(space, 0, data); break; + } +} + + +WRITE8_MEMBER( sis85c496_host_device::write_rtc ) +{ + if (offset==0) { + m_nmi_enabled = BIT(data,7); + //m_isabus->set_nmi_state((m_nmi_enabled==0) && (m_channel_check==0)); + m_ds12885->write(space,0,data); + } + else { + m_ds12885->write(space,offset,data); + } +} + +/* + +init sequence: + +config_write 00:05.0:64 00000000 @ 00ff0000 (00 to 66: select all FPM DRAMs) +00 to DRAM config +config_write 00:05.0:40 00000000 @ 000000ff (CPU config: slowest DRAM, no cache, type = 486DX2) +config_write 00:05.0:44 00000000 @ 000000ff (disable all shadow RAM) +config_write 00:05.0:80 00000000 @ 000000ff (disable all power management) +config_write 00:05.0:88 00000000 @ 000000ff (disable all chipset timers) +config_write 00:05.0:a0 00000000 @ 00ff0000 (disable all SMI) +config_write 00:05.0:a0 00000000 @ ff000000 ( " " " ) +config_write 00:05.0:40 00000000 @ 00ff0000 (cache configure) +config_write 00:05.0:44 00000000 @ 00ff0000 (disable caching all C0000-FFFFF) +config_write 00:05.0:58 00000000 @ 00ff0000 (disable SMRAM) +70 to BIOS config +config_write 00:05.0:d0 00000070 @ 000000ff (enable BIOS ROM from E0000-FFFFF) +config_write 00:05.0:54 7a000000 @ ff000000 (chipset pin configurations) +00 to DRAM config +config_write 00:05.0:40 00000000 @ 000000ff (still 486DX2, slowest DRAM, no cache) +config_write 00:05.0:40 00000000 @ 0000ff00 (256/512K type) +config_write 00:05.0:48 000000ff @ 000000ff (set all DRAM bank boundries to 256MB) +config_write 00:05.0:48 0000ff00 @ 0000ff00 +config_write 00:05.0:48 00ff0000 @ 00ff0000 +config_write 00:05.0:48 ff000000 @ ff000000 +config_write 00:05.0:4c 000000ff @ 000000ff +config_write 00:05.0:4c 0000ff00 @ 0000ff00 +config_write 00:05.0:4c 00ff0000 @ 00ff0000 +config_write 00:05.0:4c ff000000 @ ff000000 +config_write 00:05.0:48 00000000 @ 000000ff (now set all boundries to 0MB) +config_write 00:05.0:48 00000000 @ 0000ff00 +config_write 00:05.0:48 00000000 @ 00ff0000 +config_write 00:05.0:48 00000000 @ ff000000 +config_write 00:05.0:4c 00000000 @ 000000ff +config_write 00:05.0:4c 00000000 @ 0000ff00 +config_write 00:05.0:4c 00000000 @ 00ff0000 +config_write 00:05.0:4c 00000000 @ ff000000 +config_write 00:05.0:48 00000000 @ 000000ff +config_write 00:05.0:48 00000000 @ 0000ff00 +config_write 00:05.0:48 00000000 @ 00ff0000 +config_write 00:05.0:48 00000000 @ ff000000 +config_write 00:05.0:4c 00000000 @ 000000ff +config_write 00:05.0:4c 00000000 @ 0000ff00 +config_write 00:05.0:4c 00000000 @ 00ff0000 +config_write 00:05.0:4c 00000000 @ ff000000 +config_write 00:05.0:40 00004000 @ 0000ff00 (4/8/16/32M type) +config_write 00:05.0:40 00000000 @ ff000000 +config_write 00:05.0:40 00b30000 @ 00ff0000 +config_write 00:05.0:40 00000000 @ 00ff0000 + + + +*/ \ No newline at end of file diff --git a/src/devices/machine/sis85c496.h b/src/devices/machine/sis85c496.h new file mode 100644 index 00000000000..8242b31317c --- /dev/null +++ b/src/devices/machine/sis85c496.h @@ -0,0 +1,153 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +// SiS 85c496 northbridge (PCI & CPU Memory Controller) + +#ifndef SIS85C496_H +#define SIS85C496_H + +#include "pci.h" +#include "machine/ins8250.h" +#include "machine/ds128x.h" +#include "machine/pic8259.h" +#include "machine/pit8253.h" + +#include "machine/ataintf.h" +#include "machine/at_keybc.h" + +#include "sound/spkrdev.h" +#include "machine/ram.h" +#include "machine/nvram.h" + +#include "machine/pc_lpt.h" +#include "bus/pc_kbd/pc_kbdc.h" + +#include "machine/am9517a.h" +#include "cpu/i386/i386.h" +#include "machine/at.h" + +#define MCFG_SIS85C496_ADD(_tag, _cpu_tag, _ram_size) \ + MCFG_PCI_HOST_ADD(_tag, SIS85C496, 0x10390496, 0x03, 0x00000000) \ + downcast(device)->set_cpu_tag(_cpu_tag); \ + downcast(device)->set_ram_size(_ram_size); + +class sis85c496_host_device : public pci_host_device { +public: + sis85c496_host_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + virtual void device_add_mconfig(machine_config &config) override; + + void set_cpu_tag(const char *tag); + void set_ram_size(int ram_size); + + DECLARE_READ8_MEMBER (dram_config_r) { return m_dram_config; } + DECLARE_WRITE8_MEMBER(dram_config_w) { m_dram_config = data; reset_all_mappings(); } + DECLARE_READ8_MEMBER (bios_config_r) { return m_bios_config; } + DECLARE_WRITE8_MEMBER(bios_config_w) { m_bios_config = data; reset_all_mappings(); } + DECLARE_READ32_MEMBER(mailbox_r) { return m_mailbox; } + DECLARE_WRITE32_MEMBER(mailbox_w) { COMBINE_DATA(&m_mailbox); } + DECLARE_READ8_MEMBER (isa_decoder_r) { return m_isa_decoder; } + DECLARE_WRITE8_MEMBER(isa_decoder_w) { m_isa_decoder = data; reset_all_mappings(); } + DECLARE_READ16_MEMBER(shadow_config_r) { return m_shadctrl; } + DECLARE_WRITE16_MEMBER(shadow_config_w) { COMBINE_DATA(&m_shadctrl); printf("Shadow RAM control now %04x\n", m_shadctrl); reset_all_mappings(); } + + 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 DECLARE_ADDRESS_MAP(config_map, 32) override; + DECLARE_ADDRESS_MAP(internal_io_map, 32); + + // southbridge + DECLARE_READ8_MEMBER(at_page8_r); + DECLARE_WRITE8_MEMBER(at_page8_w); + DECLARE_READ8_MEMBER(at_portb_r); + DECLARE_WRITE8_MEMBER(at_portb_w); + DECLARE_READ8_MEMBER(get_slave_ack); + DECLARE_WRITE_LINE_MEMBER(at_pit8254_out0_changed); + DECLARE_WRITE_LINE_MEMBER(at_pit8254_out1_changed); + DECLARE_WRITE_LINE_MEMBER(at_pit8254_out2_changed); + DECLARE_WRITE_LINE_MEMBER(pc_dma_hrq_changed); + DECLARE_READ8_MEMBER(pc_dma8237_0_dack_r); + DECLARE_READ8_MEMBER(pc_dma8237_1_dack_r); + DECLARE_READ8_MEMBER(pc_dma8237_2_dack_r); + DECLARE_READ8_MEMBER(pc_dma8237_3_dack_r); + DECLARE_READ8_MEMBER(pc_dma8237_5_dack_r); + DECLARE_READ8_MEMBER(pc_dma8237_6_dack_r); + DECLARE_READ8_MEMBER(pc_dma8237_7_dack_r); + DECLARE_WRITE8_MEMBER(pc_dma8237_0_dack_w); + DECLARE_WRITE8_MEMBER(pc_dma8237_1_dack_w); + DECLARE_WRITE8_MEMBER(pc_dma8237_2_dack_w); + DECLARE_WRITE8_MEMBER(pc_dma8237_3_dack_w); + DECLARE_WRITE8_MEMBER(pc_dma8237_5_dack_w); + DECLARE_WRITE8_MEMBER(pc_dma8237_6_dack_w); + DECLARE_WRITE8_MEMBER(pc_dma8237_7_dack_w); + DECLARE_WRITE_LINE_MEMBER(at_dma8237_out_eop); + DECLARE_WRITE_LINE_MEMBER(pc_dack0_w); + DECLARE_WRITE_LINE_MEMBER(pc_dack1_w); + DECLARE_WRITE_LINE_MEMBER(pc_dack2_w); + DECLARE_WRITE_LINE_MEMBER(pc_dack3_w); + DECLARE_WRITE_LINE_MEMBER(pc_dack4_w); + DECLARE_WRITE_LINE_MEMBER(pc_dack5_w); + DECLARE_WRITE_LINE_MEMBER(pc_dack6_w); + DECLARE_WRITE_LINE_MEMBER(pc_dack7_w); + DECLARE_READ8_MEMBER(ide_read_cs1_r); + DECLARE_WRITE8_MEMBER(ide_write_cs1_w); + DECLARE_READ8_MEMBER(ide2_read_cs1_r); + DECLARE_WRITE8_MEMBER(ide2_write_cs1_w); + DECLARE_READ8_MEMBER(at_dma8237_2_r); + DECLARE_WRITE8_MEMBER(at_dma8237_2_w); + DECLARE_READ8_MEMBER(at_keybc_r); + DECLARE_WRITE8_MEMBER(at_keybc_w); + DECLARE_WRITE8_MEMBER(write_rtc); + DECLARE_READ8_MEMBER(pc_dma_read_byte); + DECLARE_WRITE8_MEMBER(pc_dma_write_byte); + DECLARE_READ8_MEMBER(pc_dma_read_word); + DECLARE_WRITE8_MEMBER(pc_dma_write_word); + + +protected: + virtual void device_start() override; + virtual void device_reset() override; + + void map_bios(address_space *memory_space, uint32_t start, uint32_t end); + + +private: + required_device m_maincpu; + required_device m_pic8259_master; + required_device m_pic8259_slave; + required_device m_dma8237_1; + required_device m_dma8237_2; + required_device m_pit8254; + required_device m_keybc; + required_device m_speaker; + required_device m_ds12885; + required_device m_pc_kbdc; + + uint8_t m_at_spkrdata; + uint8_t m_pit_out2; + int m_dma_channel; + bool m_cur_eop; + uint8_t m_dma_offset[2][4]; + uint8_t m_at_pages[0x10]; + uint16_t m_dma_high_byte; + uint8_t m_at_speaker; + bool m_refresh; + void pc_select_dma_channel(int channel, bool state); + void at_speaker_set_spkrdata(uint8_t data); + uint8_t m_channel_check; + uint8_t m_nmi_enabled; + + const char *cpu_tag; + int ram_size; + cpu_device *cpu; + std::vector ram; + uint32_t m_mailbox; + uint8_t m_bios_config, m_dram_config, m_isa_decoder; + uint16_t m_shadctrl; +}; + +DECLARE_DEVICE_TYPE(SIS85C496, sis85c496_host_device) + +#endif diff --git a/src/mame/drivers/mtouchxl.cpp b/src/mame/drivers/mtouchxl.cpp index 1f9f9d3f6cf..ecb21ff41f8 100644 --- a/src/mame/drivers/mtouchxl.cpp +++ b/src/mame/drivers/mtouchxl.cpp @@ -26,6 +26,9 @@ ***************************************************************************/ +// use under construction modern PCI SiS 85c496/497 chipset +//#define REAL_PCI_CHIPSET + #include "emu.h" #include "bus/isa/isa_cards.h" #include "cpu/i386/i386.h" @@ -39,8 +42,10 @@ #include "machine/bankdev.h" #include "machine/intelfsh.h" #include "machine/ds128x.h" -#include "machine/ds2401.h" #include "machine/ds1205.h" +#ifdef REAL_PCI_CHIPSET +#include "machine/sis85c496.h" +#endif #include "sound/ad1848.h" #include "speaker.h" @@ -50,17 +55,19 @@ public: mtxl_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu"), +#ifndef REAL_PCI_CHIPSET m_mb(*this, "mb"), +#endif m_ram(*this, RAM_TAG), m_iocard(*this, "dbank"), - //m_ibutton(*this, "ibutton"), m_multikey(*this, "multikey") - { } + { } required_device m_maincpu; +#ifndef REAL_PCI_CHIPSET required_device m_mb; +#endif required_device m_ram; required_device m_iocard; - //optional_device m_ibutton; optional_device m_multikey; void machine_start() override; void machine_reset() override; @@ -94,15 +101,18 @@ WRITE8_MEMBER(mtxl_state::key_w) static ADDRESS_MAP_START( at32_map, AS_PROGRAM, 32, mtxl_state ) ADDRESS_MAP_UNMAP_HIGH + #ifndef REAL_PCI_CHIPSET AM_RANGE(0x00000000, 0x0009ffff) AM_RAMBANK("bank10") AM_RANGE(0x000c8000, 0x000cffff) AM_RAM AM_SHARE("nvram") AM_RANGE(0x000d0000, 0x000dffff) AM_DEVICE("dbank", address_map_bank_device, amap32) AM_RANGE(0x000e0000, 0x000fffff) AM_ROM AM_REGION("bios", 0) AM_RANGE(0xfffe0000, 0xffffffff) AM_ROM AM_REGION("bios", 0) + #endif ADDRESS_MAP_END static ADDRESS_MAP_START( at32_io, AS_IO, 32, mtxl_state ) ADDRESS_MAP_UNMAP_HIGH + #ifndef REAL_PCI_CHIPSET AM_RANGE(0x0000, 0x001f) AM_DEVREADWRITE8("mb:dma8237_1", am9517a_device, read, write, 0xffffffff) AM_RANGE(0x0020, 0x003f) AM_DEVREADWRITE8("mb:pic8259_master", pic8259_device, read, write, 0xffffffff) AM_RANGE(0x0040, 0x005f) AM_DEVREADWRITE8("mb:pit8254", pit8254_device, read, write, 0xffffffff) @@ -113,11 +123,14 @@ static ADDRESS_MAP_START( at32_io, AS_IO, 32, mtxl_state ) AM_RANGE(0x00a0, 0x00bf) AM_DEVREADWRITE8("mb:pic8259_slave", pic8259_device, read, write, 0xffffffff) AM_RANGE(0x00c0, 0x00df) AM_DEVREADWRITE8("mb:dma8237_2", am9517a_device, read, write, 0x00ff00ff) AM_RANGE(0x0224, 0x0227) AM_DEVREADWRITE8("cs4231", ad1848_device, read, write, 0xffffffff) + #endif AM_RANGE(0x0228, 0x022b) AM_READ_PORT("Unknown") AM_RANGE(0x022c, 0x022f) AM_WRITE8(bank_w, 0xff000000) AM_RANGE(0x022c, 0x022f) AM_READWRITE8(key_r, key_w, 0x0000ff00) AM_RANGE(0x022c, 0x022f) AM_READ8(coin_r, 0x000000ff) + #ifndef REAL_PCI_CHIPSET AM_RANGE(0x03f8, 0x03ff) AM_DEVREADWRITE8("ns16550", ns16550_device, ins8250_r, ins8250_w, 0xffffffff) + #endif ADDRESS_MAP_END static ADDRESS_MAP_START( dbank_map, AS_PROGRAM, 32, mtxl_state ) @@ -146,6 +159,7 @@ INPUT_PORTS_END void mtxl_state::machine_start() { +#ifndef REAL_PCI_CHIPSET address_space& space = m_maincpu->space(AS_PROGRAM); /* MESS managed RAM */ @@ -158,6 +172,7 @@ void mtxl_state::machine_start() space.install_write_bank(0x100000, ram_limit - 1, "bank1"); membank("bank1")->set_base(m_ram->pointer() + 0xa0000); } +#endif } void mtxl_state::machine_reset() @@ -165,6 +180,7 @@ void mtxl_state::machine_reset() m_iocard->set_bank(0); } +#ifndef REAL_PCI_CHIPSET static SLOT_INTERFACE_START(mt6k_ata_devices) SLOT_INTERFACE("cdrom", ATAPI_FIXED_CDROM) SLOT_INTERFACE_END @@ -176,11 +192,13 @@ static MACHINE_CONFIG_START(cdrom) MCFG_SLOT_DEFAULT_OPTION("") MCFG_SLOT_FIXED(true) MACHINE_CONFIG_END +#endif static MACHINE_CONFIG_START( at486 ) MCFG_CPU_ADD("maincpu", I486DX4, 33000000) MCFG_CPU_PROGRAM_MAP(at32_map) MCFG_CPU_IO_MAP(at32_io) +#ifndef REAL_PCI_CHIPSET MCFG_CPU_IRQ_ACKNOWLEDGE_DEVICE("mb:pic8259_master", pic8259_device, inta_cb) MCFG_DEVICE_ADD("mb", AT_MB, 0) @@ -215,7 +233,7 @@ static MACHINE_CONFIG_START( at486 ) MCFG_DS12885_ADD("mb:rtc") MCFG_MC146818_IRQ_HANDLER(DEVWRITELINE("pic8259_slave", pic8259_device, ir0_w)) MCFG_MC146818_CENTURY_INDEX(0x32) - +#endif /* internal ram */ MCFG_RAM_ADD(RAM_TAG) MCFG_RAM_DEFAULT_SIZE("32M") // Early XL games had 8 MB RAM, 6000 and later require 32MB @@ -232,13 +250,25 @@ static MACHINE_CONFIG_START( at486 ) /* Security key */ MCFG_DS1205_ADD("multikey") + +#ifdef REAL_PCI_CHIPSET + /* PCI root */ + MCFG_PCI_ROOT_ADD( ":pci") + MCFG_SIS85C496_ADD(":pci:05.0", ":maincpu", 32*1024*1024) +#endif MACHINE_CONFIG_END +#ifdef REAL_PCI_CHIPSET +#define MOTHERBOARD_ROMS \ + ROM_REGION(0x20000, ":pci:05.0", 0) \ + ROM_LOAD( "094572516 bios - 486.bin", 0x000000, 0x020000, CRC(1c0b3ba0) SHA1(ff86dd6e476405e716ac7a4de4a216d2d2b49f15)) +#else #define MOTHERBOARD_ROMS \ ROM_REGION(0x20000, "bios", 0) \ ROM_LOAD("prom.mb", 0x10000, 0x10000, BAD_DUMP CRC(e44bfd3c) SHA1(c07ec94e11efa30e001f39560010112f73cc0016) ) \ ROM_REGION(0x80, "mb:rtc", 0) \ ROM_LOAD("mb_rtc", 0, 0x80, BAD_DUMP CRC(b724e5d3) SHA1(45a19ec4201d2933d033689b7a01a0260962fb0b)) +#endif ROM_START( mtouchxl ) MOTHERBOARD_ROMS @@ -369,7 +399,7 @@ ROM_END ***************************************************************************/ -// YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS +/* YEAR NAME PARENT COMPAT MACHINE INPUT DEVICE INIT COMPANY FULLNAME */ // Any indicates this is from a CD-R at a trade show that was claimed to be a prototype, but R1 is several versions in? COMP ( 1997, mtouchxl, 0, 0, at486, mtouchxl, mtxl_state, 0, "Merit Industries", "MegaTouch XL (Version R1, prototype?)", 0 ) COMP ( 1998, mtchxl5k, 0, 0, at486, mtouchxl, mtxl_state, 0, "Merit Industries", "MegaTouch XL Super 5000 (Version R5I)", MACHINE_NOT_WORKING ) -- cgit v1.2.3