nforcepc.cpp: start adding ITE IT8703F-A SuperIO (nw)

The device is undocumented but it is very similar to Winbond W83627 chips.
This commit is contained in:
yz70s 2019-04-24 20:04:18 +02:00
parent 9e850ffe14
commit acc073745a
2 changed files with 356 additions and 2 deletions

View File

@ -333,6 +333,273 @@ void as99127f_sensor3_device::device_start()
memset(buffer, 0, sizeof(buffer));
}
// ITE IT8703F-A SuperIO
DEFINE_DEVICE_TYPE(IT8703F, it8703f_device, "it8703f_device", "ITE IT8703F-A SuperIO")
it8703f_device::it8703f_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, IT8703F, tag, owner, clock)
, mode(OperatingMode::Run)
, config_key_step(0)
, config_index(0)
, logical_device(0)
, pin_reset_callback(*this)
, pin_gatea20_callback(*this)
, m_kbdc(*this, "pc_kbdc")
{
memset(global_configuration_registers, 0, sizeof(global_configuration_registers));
memset(configuration_registers, 0, sizeof(configuration_registers));
for (int n = 0; n < 13; n++)
enabled_logical[n] = false;
}
void it8703f_device::device_start()
{
pin_reset_callback.resolve_safe();
pin_gatea20_callback.resolve_safe();
}
void it8703f_device::internal_memory_map(address_map &map)
{
}
void it8703f_device::internal_io_map(address_map &map)
{
map(0x002e, 0x002f).rw(FUNC(it8703f_device::read_it8703f), FUNC(it8703f_device::write_it8703f));
}
uint16_t it8703f_device::get_base_address(int logical, int index)
{
int position = index * 2 + 0x60;
return ((uint16_t)configuration_registers[logical][position] << 8) + (uint16_t)configuration_registers[logical][position + 1];
}
void it8703f_device::device_add_mconfig(machine_config &config)
{
// keyboard
KBDC8042(config, m_kbdc);
m_kbdc->set_keyboard_type(kbdc8042_device::KBDC8042_PS2);
m_kbdc->input_buffer_full_callback().set(FUNC(it8703f_device::irq_keyboard_w));
m_kbdc->system_reset_callback().set(FUNC(it8703f_device::kbdp20_gp20_reset_w));
m_kbdc->gate_a20_callback().set(FUNC(it8703f_device::kbdp21_gp25_gatea20_w));
}
READ8_MEMBER(it8703f_device::read_it8703f)
{
if (offset == 0)
{
if (mode == OperatingMode::Run)
return 0;
return config_index;
}
else if (offset == 1)
{
if (mode == OperatingMode::Run)
return 0;
if (config_index < 0x30)
return read_global_configuration_register(config_index);
else
return read_logical_configuration_register(config_index);
}
else
return 0;
}
WRITE8_MEMBER(it8703f_device::write_it8703f)
{
uint8_t byt;
if (offset == 0)
{
byt = data & 0xff;
if (mode == OperatingMode::Run)
{
if (byt != 0x87)
return;
config_key_step++;
if (config_key_step > 1)
{
config_key_step = 0;
mode = OperatingMode::Configuration;
}
}
else
{
if (byt == 0xaa)
{
mode = OperatingMode::Run;
return;
}
config_index = byt;
}
}
else if (offset == 1)
{
if (mode == OperatingMode::Run)
return;
byt = data & 0xff;
if (config_index < 0x30)
write_global_configuration_register(config_index, byt);
else
write_logical_configuration_register(config_index, byt);
}
else
return;
}
void it8703f_device::write_global_configuration_register(int index, int data)
{
global_configuration_registers[index] = data;
switch (index)
{
case 7:
logical_device = data;
logerror("Selected logical device %d\n", data);
break;
}
logerror("Write global configuration register %02X = %02X\n", index, data);
}
void it8703f_device::write_logical_configuration_register(int index, int data)
{
configuration_registers[logical_device][index] = data;
switch (logical_device)
{
case LogicalDevice::Keyboard:
if (index == 0x30)
{
if (data & 1)
{
if (enabled_logical[LogicalDevice::Keyboard] == false)
map_keyboard_addresses();
enabled_logical[LogicalDevice::Keyboard] = true;
logerror("Enabled Keyboard\n");
}
else
{
if (enabled_logical[LogicalDevice::Keyboard] == true)
unmap_keyboard_addresses();
enabled_logical[LogicalDevice::Keyboard] = false;
}
}
break;
}
}
uint16_t it8703f_device::read_global_configuration_register(int index)
{
uint16_t ret = 0;
ret = global_configuration_registers[index];
switch (index)
{
case 7:
ret = logical_device;
break;
}
logerror("Read global configuration register %02X = %02X\n", index, ret);
return ret;
}
uint16_t it8703f_device::read_logical_configuration_register(int index)
{
return configuration_registers[logical_device][index];
}
WRITE_LINE_MEMBER(it8703f_device::irq_keyboard_w)
{
if (enabled_logical[LogicalDevice::Keyboard] == false)
return;
lpchost->set_virtual_line(configuration_registers[LogicalDevice::Keyboard][0x70], state ? ASSERT_LINE : CLEAR_LINE);
}
WRITE_LINE_MEMBER(it8703f_device::kbdp21_gp25_gatea20_w)
{
if (enabled_logical[LogicalDevice::Keyboard] == false)
return;
pin_gatea20_callback(state);
}
WRITE_LINE_MEMBER(it8703f_device::kbdp20_gp20_reset_w)
{
if (enabled_logical[LogicalDevice::Keyboard] == false)
return;
pin_reset_callback(state);
}
void it8703f_device::map_keyboard(address_map &map)
{
map(0x0, 0x0).rw(FUNC(it8703f_device::at_keybc_r), FUNC(it8703f_device::at_keybc_w));
map(0x4, 0x4).rw(FUNC(it8703f_device::keybc_status_r), FUNC(it8703f_device::keybc_command_w));
}
void it8703f_device::unmap_keyboard(address_map &map)
{
map(0x0, 0x0).noprw();
map(0x4, 0x4).noprw();
}
READ8_MEMBER(it8703f_device::at_keybc_r)
{
switch (offset) //m_kbdc
{
case 0:
return m_kbdc->data_r(space, 0);
}
return 0xff;
}
WRITE8_MEMBER(it8703f_device::at_keybc_w)
{
switch (offset)
{
case 0:
m_kbdc->data_w(space, 0, data);
}
}
READ8_MEMBER(it8703f_device::keybc_status_r)
{
return m_kbdc->data_r(space, 4);
}
WRITE8_MEMBER(it8703f_device::keybc_command_w)
{
m_kbdc->data_w(space, 4, data);
}
void it8703f_device::map_keyboard_addresses()
{
uint16_t base = get_base_address(LogicalDevice::Keyboard, 0);
iospace->install_device(base, base + 7, *this, &it8703f_device::map_keyboard);
}
void it8703f_device::unmap_keyboard_addresses()
{
uint16_t base = get_base_address(LogicalDevice::Keyboard, 0);
iospace->install_device(base, base + 7, *this, &it8703f_device::unmap_keyboard);
}
void it8703f_device::map_extra(address_space *memory_space, address_space *io_space)
{
memspace = memory_space;
iospace = io_space;
io_space->install_device(0, 0xffff, *this, &it8703f_device::internal_io_map);
if (enabled_logical[LogicalDevice::Keyboard] == true)
map_keyboard_addresses();
}
void it8703f_device::set_host(int index, lpcbus_host_interface *host)
{
lpchost = host;
lpcindex = index;
}
/*
Machine state
*/
@ -385,7 +652,7 @@ void nforcepc_state::machine_reset()
}
const nforcepc_state::boot_state_info nforcepc_state::boot_state_infos_award[] = {
{ 0xC0, "Turn off chipset cache" },
{ 0xC0, "First basic initialization" },
{ 0, nullptr }
};
@ -440,6 +707,9 @@ void nforcepc_state::nforcepc(machine_config &config)
mcpx_isalpc_device &isa(MCPX_ISALPC(config, ":pci:01.0", 0, 0x10430c11)); // 10de:01b2 NVIDIA Corporation nForce ISA Bridge (LPC bus)
isa.boot_state_hook().set(FUNC(nforcepc_state::boot_state_award_w));
isa.interrupt_output().set(FUNC(nforcepc_state::maincpu_interrupt));
it8703f_device &ite(IT8703F(config, ":pci:01.0:0", 0));
ite.pin_reset().set_inputline(":maincpu", INPUT_LINE_RESET);
ite.pin_gatea20().set_inputline(":maincpu", INPUT_LINE_A20);
MCPX_SMBUS(config, ":pci:01.1", 0); // 10de:01b4 NVIDIA Corporation nForce PCI System Management (SMBus)
SMBUS_ROM(config, ":pci:01.1:050", 0, test_spd_data, sizeof(test_spd_data)); // these 3 are on smbus number 0
SMBUS_LOGGER(config, ":pci:01.1:051", 0);
@ -472,7 +742,7 @@ ROM_START(nforcepc)
ROM_END
static INPUT_PORTS_START(nforcepc)
//PORT_INCLUDE(at_keyboard)
PORT_INCLUDE(at_keyboard)
INPUT_PORTS_END
COMP(2002, nforcepc, 0, 0, nforcepc, nforcepc, nforcepc_state, empty_init, "Nvidia", "Nvidia nForce PC (CRUSH11/12)", MACHINE_IS_SKELETON)

View File

@ -4,6 +4,7 @@
#define MAME_MACHINE_NFORCEPC_H
#pragma once
#include "machine/8042kbdc.h"
// NVIDIA Corporation nForce CPU bridge
@ -163,4 +164,87 @@ private:
DECLARE_DEVICE_TYPE(AS99127F_SENSOR3, as99127f_sensor3_device)
// ITE IT8703F-A SuperIO
class it8703f_device : public device_t, public lpcbus_device_interface
{
public:
it8703f_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual void map_extra(address_space *memory_space, address_space *io_space) override;
virtual void set_host(int index, lpcbus_host_interface *host) override;
virtual void device_add_mconfig(machine_config &config) override;
auto pin_reset() { return pin_reset_callback.bind(); }
auto pin_gatea20() { return pin_gatea20_callback.bind(); }
// keyboard
DECLARE_WRITE_LINE_MEMBER(irq_keyboard_w);
DECLARE_WRITE_LINE_MEMBER(kbdp21_gp25_gatea20_w);
DECLARE_WRITE_LINE_MEMBER(kbdp20_gp20_reset_w);
void map_keyboard(address_map &map);
void unmap_keyboard(address_map &map);
DECLARE_READ8_MEMBER(read_it8703f);
DECLARE_WRITE8_MEMBER(write_it8703f);
// keyboard
DECLARE_READ8_MEMBER(at_keybc_r);
DECLARE_WRITE8_MEMBER(at_keybc_w);
DECLARE_READ8_MEMBER(keybc_status_r);
DECLARE_WRITE8_MEMBER(keybc_command_w);
protected:
virtual void device_start() override;
private:
enum OperatingMode
{
Run = 0,
Configuration = 1
} mode;
enum LogicalDevice
{
FDC = 0,
Parallel,
Serial1,
Serial2,
Keyboard = 5,
ConsumerIR,
Gpio1,
Gpio2,
Gpio34,
ACPI,
Gpio567 = 12
};
int config_key_step;
int config_index;
int logical_device;
uint8_t global_configuration_registers[0x30];
uint8_t configuration_registers[13][0x100];
devcb_write_line pin_reset_callback;
devcb_write_line pin_gatea20_callback;
required_device<kbdc8042_device> m_kbdc;
bool enabled_logical[13];
lpcbus_host_interface *lpchost;
int lpcindex;
address_space *memspace;
address_space *iospace;
void internal_memory_map(address_map &map);
void internal_io_map(address_map &map);
uint16_t get_base_address(int logical, int index);
void map_keyboard_addresses();
void unmap_keyboard_addresses();
void write_global_configuration_register(int index, int data);
void write_logical_configuration_register(int index, int data);
void write_keyboard_configuration_register(int index, int data);
uint16_t read_global_configuration_register(int index);
uint16_t read_logical_configuration_register(int index);
uint16_t read_keyboard_configuration_register(int index);
};
DECLARE_DEVICE_TYPE(IT8703F, it8703f_device)
#endif