machine/pc87306: preliminary COM1/COM2/LPT1 support

This commit is contained in:
angelosa 2024-02-26 02:53:30 +01:00
parent 8d8da3e93a
commit 71847a39a8
5 changed files with 269 additions and 48 deletions

View File

@ -9,6 +9,10 @@ TODO:
- Add Trio32/Trio64, pillage roms from isa/svga_s3
- Make ViRGE to derive from here rather than reinventing the wheel
Notes:
- Some of these BIOSes are buggy in SDD VBETEST.EXE, doesn't return any video mode,
Reportedly mirocrys (vision964) and no9fx771 (vision968) has this inconvenient.
**************************************************************************************************/
#include "emu.h"
@ -191,7 +195,7 @@ vision968_pci_device::vision968_pci_device(const machine_config &mconfig, const
ROM_START( vision968 )
ROM_REGION32_LE( 0x8000, "bios", ROMREGION_ERASEFF )
ROM_DEFAULT_BIOS("no9fx771")
ROM_DEFAULT_BIOS("elsaw2k")
ROM_SYSTEM_BIOS( 0, "no9fx771", "Number Nine 9FX MotionFX 771 v2.45.11" )
ROMX_LOAD( "no9motionfx771.bin", 0x0000, 0x8000, CRC(7732e382) SHA1(9ec2fe056712cef39bd8380d406be3c874ea5ec9), ROM_BIOS(0) )

View File

@ -1,13 +1,14 @@
// license:BSD-3-Clause
// copyright-holders: Angelo Salese
/***************************************************************************
/**************************************************************************************************
National Semiconductor PC87306 Super I/O
TODO:
- Barely enough to make it surpass POST test 0x05 in misc/odyssey.cpp
- Barely enough to make it surpass POST test 0x05 in misc/odyssey.cpp;
- COM1/COM2/LPT1 address and irq select;
***************************************************************************/
**************************************************************************************************/
#include "emu.h"
#include "bus/isa/isa.h"
@ -32,18 +33,19 @@ pc87306_device::pc87306_device(const machine_config &mconfig, const char *tag, d
, m_space_config("superio_config_regs", ENDIANNESS_LITTLE, 8, 8, 0, address_map_constructor(FUNC(pc87306_device::config_map), this))
, m_kbdc(*this, "pc_kbdc")
, m_rtc(*this, "rtc")
//, m_logical_view(*this, "logical_view")
, m_pc_com(*this, "uart%d", 0U)
, m_pc_lpt(*this, "lpta")
, m_gp20_reset_callback(*this)
, m_gp25_gatea20_callback(*this)
, m_irq1_callback(*this)
, m_irq8_callback(*this)
, m_irq9_callback(*this)
// , m_txd1_callback(*this)
// , m_ndtr1_callback(*this)
// , m_nrts1_callback(*this)
// , m_txd2_callback(*this)
// , m_ndtr2_callback(*this)
// , m_nrts2_callback(*this)
, m_txd1_callback(*this)
, m_ndtr1_callback(*this)
, m_nrts1_callback(*this)
, m_txd2_callback(*this)
, m_ndtr2_callback(*this)
, m_nrts2_callback(*this)
{ }
@ -89,6 +91,21 @@ void pc87306_device::device_add_mconfig(machine_config &config)
at_keyboard_device &at_keyb(AT_KEYB(config, "at_keyboard", pc_keyboard_device::KEYBOARD_TYPE::AT, 1));
at_keyb.keypress().set(m_kbdc, FUNC(kbdc8042_device::keyboard_w));
PC_LPT(config, m_pc_lpt);
m_pc_lpt->irq_handler().set(FUNC(pc87306_device::irq_parallel_w));
NS16550(config, m_pc_com[0], XTAL(1'843'200));
m_pc_com[0]->out_int_callback().set(FUNC(pc87306_device::irq_serial1_w));
m_pc_com[0]->out_tx_callback().set(FUNC(pc87306_device::txd_serial1_w));
m_pc_com[0]->out_dtr_callback().set(FUNC(pc87306_device::dtr_serial1_w));
m_pc_com[0]->out_rts_callback().set(FUNC(pc87306_device::rts_serial1_w));
NS16550(config, m_pc_com[1], XTAL(1'843'200));
m_pc_com[1]->out_int_callback().set(FUNC(pc87306_device::irq_serial2_w));
m_pc_com[1]->out_tx_callback().set(FUNC(pc87306_device::txd_serial2_w));
m_pc_com[1]->out_dtr_callback().set(FUNC(pc87306_device::dtr_serial2_w));
m_pc_com[1]->out_rts_callback().set(FUNC(pc87306_device::rts_serial2_w));
}
void pc87306_device::remap(int space_id, offs_t start, offs_t end)
@ -107,6 +124,16 @@ void pc87306_device::remap(int space_id, offs_t start, offs_t end)
if (BIT(m_krr, 3))
m_isa->install_device(0x70, 0x71, read8sm_delegate(*this, FUNC(pc87306_device::rtc_r)), write8sm_delegate(*this, FUNC(pc87306_device::rtc_w)));
if (BIT(m_fer, 0))
m_isa->install_device(0x378, 0x37f, read8sm_delegate(*m_pc_lpt, FUNC(pc_lpt_device::read)), write8sm_delegate(*m_pc_lpt, FUNC(pc_lpt_device::write)));
if (BIT(m_fer, 1))
m_isa->install_device(0x3f8, 0x3ff, read8sm_delegate(*m_pc_com[0], FUNC(ns16450_device::ins8250_r)), write8sm_delegate(*m_pc_com[0], FUNC(ns16450_device::ins8250_w)));
if (BIT(m_fer, 2))
m_isa->install_device(0x2f8, 0x2ff, read8sm_delegate(*m_pc_com[1], FUNC(ns16450_device::ins8250_r)), write8sm_delegate(*m_pc_com[1], FUNC(ns16450_device::ins8250_w)));
}
}
@ -140,8 +167,8 @@ void pc87306_device::write(offs_t offset, u8 data)
void pc87306_device::config_map(address_map &map)
{
// map(0x00, 0x00) FER Function Enable Register
// map(0x01, 0x01) FAR Function Address Register
map(0x00, 0x00).rw(FUNC(pc87306_device::fer_r), FUNC(pc87306_device::fer_w));
map(0x01, 0x01).rw(FUNC(pc87306_device::far_r), FUNC(pc87306_device::far_w));
// map(0x02, 0x02) PTR Power and Test Register
// map(0x03, 0x03) FCR Function Control Register
// map(0x04, 0x04) PCR Printer Control Register
@ -171,8 +198,49 @@ void pc87306_device::config_map(address_map &map)
// map(0x1c, 0x1c) PNP1 Plug and Play Configuration 1 Register
}
// [0x05] KRR KBC and RTC Control Register
/*
* [0x00] FER Function Enable Register
* x--- ---- IDE address select
* -x-- ---- IDE i/f enable
* --x- ---- FDC address select
* ---x ---- (0) x2 floppy drives (1) x4 floppy drives
* ---- x--- FDC enable
* ---- -x-- UART2 enable
* ---- --x- UART1 enable
* ---- ---x Parallel Port enable
*/
u8 pc87306_device::fer_r(offs_t offset)
{
return m_fer;
}
void pc87306_device::fer_w(offs_t offset, u8 data)
{
m_fer = data;
remap(AS_IO, 0, 0x400);
}
/*
* [0x01] FAR Function Address Register
* xxxx ---- UART2 address select
* xx-- xx-- UART1 address select
* ---- --xx parallel address select
*/
u8 pc87306_device::far_r(offs_t offset)
{
return m_far;
}
void pc87306_device::far_w(offs_t offset, u8 data)
{
m_far = data;
remap(AS_IO, 0, 0x400);
}
/*
* [0x05] KRR KBC and RTC Control Register
*
* x--- ---- KBC clock source select (0) X1 clock (1) SYSCLK
* --x- ---- RAMSREL RTC bank select
* ---- x--- RTC enable bit
@ -254,6 +322,128 @@ void pc87306_device::irq_mouse_w(int state)
request_irq(12, state ? ASSERT_LINE : CLEAR_LINE);
}
/*
* Serial
*/
void pc87306_device::irq_serial1_w(int state)
{
if (!(BIT(m_fer, 1)))
return;
request_irq(3, state ? ASSERT_LINE : CLEAR_LINE);
}
void pc87306_device::irq_serial2_w(int state)
{
if (!(BIT(m_fer, 2)))
return;
request_irq(4, state ? ASSERT_LINE : CLEAR_LINE);
}
void pc87306_device::txd_serial1_w(int state)
{
if (!(BIT(m_fer, 1)))
return;
m_txd1_callback(state);
}
void pc87306_device::txd_serial2_w(int state)
{
if (!(BIT(m_fer, 2)))
return;
m_txd2_callback(state);
}
void pc87306_device::dtr_serial1_w(int state)
{
if (!(BIT(m_fer, 1)))
return;
m_ndtr1_callback(state);
}
void pc87306_device::dtr_serial2_w(int state)
{
if (!(BIT(m_fer, 2)))
return;
m_ndtr2_callback(state);
}
void pc87306_device::rts_serial1_w(int state)
{
if (!(BIT(m_fer, 1)))
return;
m_nrts1_callback(state);
}
void pc87306_device::rts_serial2_w(int state)
{
if (!(BIT(m_fer, 2)))
return;
m_nrts2_callback(state);
}
void pc87306_device::rxd1_w(int state)
{
m_pc_com[0]->rx_w(state);
}
void pc87306_device::ndcd1_w(int state)
{
m_pc_com[0]->dcd_w(state);
}
void pc87306_device::ndsr1_w(int state)
{
m_pc_com[0]->dsr_w(state);
}
void pc87306_device::nri1_w(int state)
{
m_pc_com[0]->ri_w(state);
}
void pc87306_device::ncts1_w(int state)
{
m_pc_com[0]->cts_w(state);
}
void pc87306_device::rxd2_w(int state)
{
m_pc_com[1]->rx_w(state);
}
void pc87306_device::ndcd2_w(int state)
{
m_pc_com[1]->dcd_w(state);
}
void pc87306_device::ndsr2_w(int state)
{
m_pc_com[1]->dsr_w(state);
}
void pc87306_device::nri2_w(int state)
{
m_pc_com[1]->ri_w(state);
}
void pc87306_device::ncts2_w(int state)
{
m_pc_com[1]->cts_w(state);
}
/*
* Parallel
*/
void pc87306_device::irq_parallel_w(int state)
{
if (!(BIT(m_fer, 0)))
return;
request_irq(5, state ? ASSERT_LINE : CLEAR_LINE);
}
void pc87306_device::request_irq(int irq, int state)
{
switch (irq)

View File

@ -9,6 +9,8 @@
#include "bus/isa/isa.h"
#include "machine/8042kbdc.h"
#include "machine/ds128x.h"
#include "machine/ins8250.h"
#include "machine/pc_lpt.h"
class pc87306_device : public device_t,
public device_isa16_card_interface,
@ -25,12 +27,23 @@ public:
auto irq1() { return m_irq1_callback.bind(); }
auto irq8() { return m_irq8_callback.bind(); }
auto irq9() { return m_irq9_callback.bind(); }
// auto txd1() { return m_txd1_callback.bind(); }
// auto ndtr1() { return m_ndtr1_callback.bind(); }
// auto nrts1() { return m_nrts1_callback.bind(); }
// auto txd2() { return m_txd2_callback.bind(); }
// auto ndtr2() { return m_ndtr2_callback.bind(); }
// auto nrts2() { return m_nrts2_callback.bind(); }
auto txd1() { return m_txd1_callback.bind(); }
auto ndtr1() { return m_ndtr1_callback.bind(); }
auto nrts1() { return m_nrts1_callback.bind(); }
auto txd2() { return m_txd2_callback.bind(); }
auto ndtr2() { return m_ndtr2_callback.bind(); }
auto nrts2() { return m_nrts2_callback.bind(); }
void rxd1_w(int state);
void ndcd1_w(int state);
void ndsr1_w(int state);
void nri1_w(int state);
void ncts1_w(int state);
void rxd2_w(int state);
void ndcd2_w(int state);
void ndsr2_w(int state);
void nri2_w(int state);
void ncts2_w(int state);
protected:
virtual void device_start() override;
@ -44,19 +57,20 @@ private:
required_device<kbdc8042_device> m_kbdc;
required_device<ds12885_device> m_rtc;
// memory_view m_logical_view;
required_device_array<ns16550_device, 2> m_pc_com;
required_device<pc_lpt_device> m_pc_lpt;
devcb_write_line m_gp20_reset_callback;
devcb_write_line m_gp25_gatea20_callback;
devcb_write_line m_irq1_callback;
devcb_write_line m_irq8_callback;
devcb_write_line m_irq9_callback;
// devcb_write_line m_txd1_callback;
// devcb_write_line m_ndtr1_callback;
// devcb_write_line m_nrts1_callback;
// devcb_write_line m_txd2_callback;
// devcb_write_line m_ndtr2_callback;
// devcb_write_line m_nrts2_callback;
devcb_write_line m_txd1_callback;
devcb_write_line m_ndtr1_callback;
devcb_write_line m_nrts1_callback;
devcb_write_line m_txd2_callback;
devcb_write_line m_ndtr2_callback;
devcb_write_line m_nrts2_callback;
void request_irq(int irq, int state);
@ -65,6 +79,12 @@ private:
void config_map(address_map &map);
u8 far_r(offs_t offset);
void far_w(offs_t offset, u8 data);
u8 fer_r(offs_t offset);
void fer_w(offs_t offset, u8 data);
u8 keybc_status_r(offs_t offset);
void keybc_command_w(offs_t offset, u8 data);
u8 rtc_r(offs_t offset);
@ -79,10 +99,23 @@ private:
u8 krr_r(offs_t offset);
void krr_w(offs_t offset, u8 data);
void irq_parallel_w(int state);
void irq_serial1_w(int state);
void txd_serial1_w(int state);
void dtr_serial1_w(int state);
void rts_serial1_w(int state);
void irq_serial2_w(int state);
void txd_serial2_w(int state);
void dtr_serial2_w(int state);
void rts_serial2_w(int state);
u8 m_index = 0;
u8 m_locked_state = 2;
u8 m_krr = 0;
u8 m_fer = 0;
u8 m_far = 0;
};
DECLARE_DEVICE_TYPE(PC87306, pc87306_device);

View File

@ -178,7 +178,7 @@ void gammagic_state::gammagic(machine_config &config)
ISA16_SLOT(config, "isa3", 0, "pci:07.0:isabus", pc_isa16_cards, nullptr, false);
ISA16_SLOT(config, "isa4", 0, "pci:07.0:isabus", pc_isa16_cards, nullptr, false);
rs232_port_device& serport0(RS232_PORT(config, "serport0", isa_com, nullptr)); // "microsoft_mouse"));
rs232_port_device& serport0(RS232_PORT(config, "serport0", isa_com, nullptr));
serport0.rxd_handler().set("board4:fdc37c93x", FUNC(fdc37c93x_device::rxd1_w));
serport0.dcd_handler().set("board4:fdc37c93x", FUNC(fdc37c93x_device::ndcd1_w));
serport0.dsr_handler().set("board4:fdc37c93x", FUNC(fdc37c93x_device::ndsr1_w));

View File

@ -82,9 +82,9 @@
#include "bus/pci/vision.h"
//#include "bus/rs232/hlemouse.h"
//#include "bus/rs232/null_modem.h"
//#include "bus/rs232/rs232.h"
#include "bus/rs232/rs232.h"
//#include "bus/rs232/sun_kbd.h"
//#include "bus/rs232/terminal.h"
#include "bus/rs232/terminal.h"
#include "machine/pc87306.h"
@ -137,17 +137,14 @@ void odyssey_state::national_superio_config(device_t *device)
fdc.gp25_gatea20().set_inputline(":maincpu", INPUT_LINE_A20);
fdc.irq1().set(":pci:07.0", FUNC(i82371sb_isa_device::pc_irq1_w));
fdc.irq8().set(":pci:07.0", FUNC(i82371sb_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
}
#if 0
static void isa_com(device_slot_interface &device)
{
// device.option_add("microsoft_mouse", MSFT_HLE_SERIAL_MOUSE);
@ -155,11 +152,10 @@ static void isa_com(device_slot_interface &device)
// device.option_add("wheel_mouse", WHEEL_HLE_SERIAL_MOUSE);
// device.option_add("msystems_mouse", MSYSTEMS_HLE_SERIAL_MOUSE);
// device.option_add("rotatable_mouse", ROTATABLE_HLE_SERIAL_MOUSE);
// device.option_add("terminal", SERIAL_TERMINAL);
device.option_add("terminal", SERIAL_TERMINAL);
// device.option_add("null_modem", NULL_MODEM);
// device.option_add("sun_kbd", SUN_KBD_ADAPTOR);
}
#endif
// This emulates a Tucson / Triton-II chipset, earlier i430fx TBD
// PCI config space is trusted by Intel TC430HX "Technical Product Specification" page 39
@ -210,21 +206,19 @@ void odyssey_state::odyssey(machine_config &config)
ISA16_SLOT(config, "isa4", 0, "pci:07.0:isabus", pc_isa16_cards, nullptr, false);
ISA16_SLOT(config, "isa5", 0, "pci:07.0:isabus", pc_isa16_cards, nullptr, false);
#if 0
rs232_port_device& serport0(RS232_PORT(config, "serport0", isa_com, nullptr)); // "microsoft_mouse"));
serport0.rxd_handler().set("board4:fdc37c93x", FUNC(fdc37c93x_device::rxd1_w));
serport0.dcd_handler().set("board4:fdc37c93x", FUNC(fdc37c93x_device::ndcd1_w));
serport0.dsr_handler().set("board4:fdc37c93x", FUNC(fdc37c93x_device::ndsr1_w));
serport0.ri_handler().set("board4:fdc37c93x", FUNC(fdc37c93x_device::nri1_w));
serport0.cts_handler().set("board4:fdc37c93x", FUNC(fdc37c93x_device::ncts1_w));
rs232_port_device& serport0(RS232_PORT(config, "serport0", isa_com, nullptr));
serport0.rxd_handler().set("board4:pc87306", FUNC(pc87306_device::rxd1_w));
serport0.dcd_handler().set("board4:pc87306", FUNC(pc87306_device::ndcd1_w));
serport0.dsr_handler().set("board4:pc87306", FUNC(pc87306_device::ndsr1_w));
serport0.ri_handler().set("board4:pc87306", FUNC(pc87306_device::nri1_w));
serport0.cts_handler().set("board4:pc87306", FUNC(pc87306_device::ncts1_w));
rs232_port_device &serport1(RS232_PORT(config, "serport1", isa_com, nullptr));
serport1.rxd_handler().set("board4:fdc37c93x", FUNC(fdc37c93x_device::rxd2_w));
serport1.dcd_handler().set("board4:fdc37c93x", FUNC(fdc37c93x_device::ndcd2_w));
serport1.dsr_handler().set("board4:fdc37c93x", FUNC(fdc37c93x_device::ndsr2_w));
serport1.ri_handler().set("board4:fdc37c93x", FUNC(fdc37c93x_device::nri2_w));
serport1.cts_handler().set("board4:fdc37c93x", FUNC(fdc37c93x_device::ncts2_w));
#endif
serport1.rxd_handler().set("board4:pc87306", FUNC(pc87306_device::rxd2_w));
serport1.dcd_handler().set("board4:pc87306", FUNC(pc87306_device::ndcd2_w));
serport1.dsr_handler().set("board4:pc87306", FUNC(pc87306_device::ndsr2_w));
serport1.ri_handler().set("board4:pc87306", FUNC(pc87306_device::nri2_w));
serport1.cts_handler().set("board4:pc87306", FUNC(pc87306_device::ncts2_w));
}