summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/s100/wunderbus.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/s100/wunderbus.c')
-rw-r--r--src/devices/bus/s100/wunderbus.c528
1 files changed, 528 insertions, 0 deletions
diff --git a/src/devices/bus/s100/wunderbus.c b/src/devices/bus/s100/wunderbus.c
new file mode 100644
index 00000000000..4b269a80e93
--- /dev/null
+++ b/src/devices/bus/s100/wunderbus.c
@@ -0,0 +1,528 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Morrow Designs Wunderbus I/O card emulation
+
+**********************************************************************/
+
+#include "wunderbus.h"
+#include "bus/rs232/rs232.h"
+
+
+
+//**************************************************************************
+// MACROS/CONSTANTS
+//**************************************************************************
+
+#define I8259A_TAG "13b"
+#define INS8250_1_TAG "6d"
+#define INS8250_2_TAG "5d"
+#define INS8250_3_TAG "4d"
+#define RS232_A_TAG "rs232a"
+#define RS232_B_TAG "rs232b"
+#define RS232_C_TAG "rs232c"
+#define UPD1990C_TAG "12a"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type S100_WUNDERBUS = &device_creator<s100_wunderbus_device>;
+
+
+//-------------------------------------------------
+// pic8259_interface pic_intf
+//-------------------------------------------------
+
+/*
+
+ bit description
+
+ IR0 S-100 VI0
+ IR1 S-100 VI1
+ IR2 S-100 VI2
+ IR3 Serial Device 1
+ IR4 Serial Device 2
+ IR5 Serial Device 3
+ IR6 Daisy PWR line
+ IR7 RT Clock TP line
+
+*/
+
+WRITE_LINE_MEMBER( s100_wunderbus_device::pic_int_w )
+{
+ m_bus->irq_w(state);
+}
+
+static DEVICE_INPUT_DEFAULTS_START( terminal )
+ DEVICE_INPUT_DEFAULTS( "RS232_TXBAUD", 0xff, RS232_BAUD_110 )
+ DEVICE_INPUT_DEFAULTS( "RS232_RXBAUD", 0xff, RS232_BAUD_110 )
+ DEVICE_INPUT_DEFAULTS( "RS232_STARTBITS", 0xff, RS232_STARTBITS_1 )
+ DEVICE_INPUT_DEFAULTS( "RS232_DATABITS", 0xff, RS232_DATABITS_8 )
+ DEVICE_INPUT_DEFAULTS( "RS232_PARITY", 0xff, RS232_PARITY_NONE )
+ DEVICE_INPUT_DEFAULTS( "RS232_STOPBITS", 0xff, RS232_STOPBITS_2 )
+DEVICE_INPUT_DEFAULTS_END
+
+
+//-------------------------------------------------
+// UPD1990A_INTERFACE( rtc_intf )
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( s100_wunderbus_device::rtc_tp_w )
+{
+ if (state)
+ {
+ m_rtc_tp = state;
+ m_pic->ir7_w(m_rtc_tp);
+ }
+}
+
+
+//-------------------------------------------------
+// MACHINE_CONFIG_FRAGMENT( s100_wunderbus )
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( s100_wunderbus )
+ MCFG_PIC8259_ADD(I8259A_TAG, DEVWRITELINE(DEVICE_SELF, s100_wunderbus_device, pic_int_w), VCC, NULL)
+ MCFG_DEVICE_ADD(INS8250_1_TAG, INS8250, XTAL_18_432MHz/10)
+ MCFG_INS8250_OUT_TX_CB(DEVWRITELINE(RS232_A_TAG, rs232_port_device, write_txd))
+ MCFG_INS8250_OUT_DTR_CB(DEVWRITELINE(RS232_A_TAG, rs232_port_device, write_dtr))
+ MCFG_INS8250_OUT_RTS_CB(DEVWRITELINE(RS232_A_TAG, rs232_port_device, write_rts))
+ MCFG_INS8250_OUT_INT_CB(DEVWRITELINE(I8259A_TAG, pic8259_device, ir3_w))
+ MCFG_DEVICE_ADD(INS8250_2_TAG, INS8250, XTAL_18_432MHz/10)
+ MCFG_INS8250_OUT_TX_CB(DEVWRITELINE(RS232_B_TAG, rs232_port_device, write_txd))
+ MCFG_INS8250_OUT_DTR_CB(DEVWRITELINE(RS232_B_TAG, rs232_port_device, write_dtr))
+ MCFG_INS8250_OUT_RTS_CB(DEVWRITELINE(RS232_B_TAG, rs232_port_device, write_rts))
+ MCFG_INS8250_OUT_INT_CB(DEVWRITELINE(I8259A_TAG, pic8259_device, ir4_w))
+ MCFG_DEVICE_ADD(INS8250_3_TAG, INS8250, XTAL_18_432MHz/10)
+ MCFG_INS8250_OUT_TX_CB(DEVWRITELINE(RS232_C_TAG, rs232_port_device, write_txd))
+ MCFG_INS8250_OUT_DTR_CB(DEVWRITELINE(RS232_C_TAG, rs232_port_device, write_dtr))
+ MCFG_INS8250_OUT_RTS_CB(DEVWRITELINE(RS232_C_TAG, rs232_port_device, write_rts))
+ MCFG_INS8250_OUT_INT_CB(DEVWRITELINE(I8259A_TAG, pic8259_device, ir5_w))
+
+ MCFG_RS232_PORT_ADD(RS232_A_TAG, default_rs232_devices, "terminal")
+ MCFG_RS232_RXD_HANDLER(DEVWRITELINE(INS8250_1_TAG, ins8250_uart_device, rx_w))
+ MCFG_RS232_DCD_HANDLER(DEVWRITELINE(INS8250_1_TAG, ins8250_uart_device, dcd_w))
+ MCFG_RS232_DSR_HANDLER(DEVWRITELINE(INS8250_1_TAG, ins8250_uart_device, dsr_w))
+ MCFG_RS232_RI_HANDLER(DEVWRITELINE(INS8250_1_TAG, ins8250_uart_device, ri_w))
+ MCFG_RS232_CTS_HANDLER(DEVWRITELINE(INS8250_1_TAG, ins8250_uart_device, cts_w))
+ MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS("terminal", terminal)
+
+ MCFG_RS232_PORT_ADD(RS232_B_TAG, default_rs232_devices, NULL)
+ MCFG_RS232_RXD_HANDLER(DEVWRITELINE(INS8250_2_TAG, ins8250_uart_device, rx_w))
+ MCFG_RS232_DCD_HANDLER(DEVWRITELINE(INS8250_2_TAG, ins8250_uart_device, dcd_w))
+ MCFG_RS232_DSR_HANDLER(DEVWRITELINE(INS8250_2_TAG, ins8250_uart_device, dsr_w))
+ MCFG_RS232_RI_HANDLER(DEVWRITELINE(INS8250_2_TAG, ins8250_uart_device, ri_w))
+ MCFG_RS232_CTS_HANDLER(DEVWRITELINE(INS8250_2_TAG, ins8250_uart_device, cts_w))
+
+ MCFG_RS232_PORT_ADD(RS232_C_TAG, default_rs232_devices, NULL)
+ MCFG_RS232_RXD_HANDLER(DEVWRITELINE(INS8250_3_TAG, ins8250_uart_device, rx_w))
+ MCFG_RS232_DCD_HANDLER(DEVWRITELINE(INS8250_3_TAG, ins8250_uart_device, dcd_w))
+ MCFG_RS232_DSR_HANDLER(DEVWRITELINE(INS8250_3_TAG, ins8250_uart_device, dsr_w))
+ MCFG_RS232_RI_HANDLER(DEVWRITELINE(INS8250_3_TAG, ins8250_uart_device, ri_w))
+ MCFG_RS232_CTS_HANDLER(DEVWRITELINE(INS8250_3_TAG, ins8250_uart_device, cts_w))
+
+ MCFG_UPD1990A_ADD(UPD1990C_TAG, XTAL_32_768kHz, NULL, DEVWRITELINE(DEVICE_SELF, s100_wunderbus_device, rtc_tp_w))
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor s100_wunderbus_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( s100_wunderbus );
+}
+
+
+//-------------------------------------------------
+// INPUT_PORTS( wunderbus )
+//-------------------------------------------------
+
+static INPUT_PORTS_START( wunderbus )
+ PORT_START("7C")
+ PORT_DIPNAME( 0x01, 0x00, DEF_STR( Unused ) ) PORT_DIPLOCATION("7C:1")
+ PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x3e, 0x12, "BASE Port Address" ) PORT_DIPLOCATION("7C:2,3,4,5,6")
+ PORT_DIPSETTING( 0x00, "00H" )
+ PORT_DIPSETTING( 0x02, "08H" )
+ PORT_DIPSETTING( 0x04, "10H" )
+ PORT_DIPSETTING( 0x06, "18H" )
+ PORT_DIPSETTING( 0x08, "20H" )
+ PORT_DIPSETTING( 0x0a, "28H" )
+ PORT_DIPSETTING( 0x0c, "30H" )
+ PORT_DIPSETTING( 0x0e, "38H" )
+ PORT_DIPSETTING( 0x10, "40H" )
+ PORT_DIPSETTING( 0x12, "48H" )
+ PORT_DIPSETTING( 0x14, "50H" )
+ PORT_DIPSETTING( 0x16, "58H" )
+ PORT_DIPSETTING( 0x18, "60H" )
+ PORT_DIPSETTING( 0x1a, "68H" )
+ PORT_DIPSETTING( 0x1c, "70H" )
+ PORT_DIPSETTING( 0x1e, "78H" )
+ PORT_DIPSETTING( 0x20, "80H" )
+ PORT_DIPSETTING( 0x22, "88H" )
+ PORT_DIPSETTING( 0x24, "90H" )
+ PORT_DIPSETTING( 0x26, "98H" )
+ PORT_DIPSETTING( 0x28, "A0H" )
+ PORT_DIPSETTING( 0x2a, "A8H" )
+ PORT_DIPSETTING( 0x2c, "B0H" )
+ PORT_DIPSETTING( 0x2e, "B8H" )
+ PORT_DIPSETTING( 0x30, "C0H" )
+ PORT_DIPSETTING( 0x32, "C8H" )
+ PORT_DIPSETTING( 0x34, "D0H" )
+ PORT_DIPSETTING( 0x36, "D8H" )
+ PORT_DIPSETTING( 0x38, "E0H" )
+ PORT_DIPSETTING( 0x3a, "E8H" )
+ PORT_DIPSETTING( 0x3c, "F0H" )
+ PORT_DIPSETTING( 0x3e, "F8H" )
+ PORT_DIPNAME( 0x40, 0x40, "FLAG2 Polarity" ) PORT_DIPLOCATION("7C:7")
+ PORT_DIPSETTING( 0x40, "Negative" )
+ PORT_DIPSETTING( 0x00, "Positive" )
+ PORT_DIPNAME( 0x80, 0x80, "FLAG1 Polarity" ) PORT_DIPLOCATION("7C:8")
+ PORT_DIPSETTING( 0x80, "Negative" )
+ PORT_DIPSETTING( 0x00, "Positive" )
+
+ PORT_START("10A")
+ PORT_DIPNAME( 0x07, 0x00, "Baud Rate" ) PORT_DIPLOCATION("10A:1,2,3")
+ PORT_DIPSETTING( 0x00, "Automatic" )
+ PORT_DIPSETTING( 0x01, "19200" )
+ PORT_DIPSETTING( 0x02, "9600" )
+ PORT_DIPSETTING( 0x03, "4800" )
+ PORT_DIPSETTING( 0x04, "2400" )
+ PORT_DIPSETTING( 0x05, "1200" )
+ PORT_DIPSETTING( 0x06, "300" )
+ PORT_DIPSETTING( 0x07, "110" )
+ PORT_DIPNAME( 0x08, 0x00, DEF_STR( Unused ) ) PORT_DIPLOCATION("10A:4")
+ PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unused ) ) PORT_DIPLOCATION("10A:5")
+ PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x20, 0x00, DEF_STR( Unused ) ) PORT_DIPLOCATION("10A:6")
+ PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unused ) ) PORT_DIPLOCATION("10A:7")
+ PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unused ) ) PORT_DIPLOCATION("10A:8")
+ PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+INPUT_PORTS_END
+
+
+//-------------------------------------------------
+// input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor s100_wunderbus_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( wunderbus );
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// s100_wunderbus_device - constructor
+//-------------------------------------------------
+
+s100_wunderbus_device::s100_wunderbus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, S100_WUNDERBUS, "Wunderbus I/O", tag, owner, clock, "s100_wunderbus", __FILE__),
+ device_s100_card_interface(mconfig, *this),
+ m_pic(*this, I8259A_TAG),
+ m_ace1(*this, INS8250_1_TAG),
+ m_ace2(*this, INS8250_2_TAG),
+ m_ace3(*this, INS8250_3_TAG),
+ m_rtc(*this, UPD1990C_TAG),
+ m_7c(*this, "7C"),
+ m_10a(*this, "10A")
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void s100_wunderbus_device::device_start()
+{
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void s100_wunderbus_device::device_reset()
+{
+}
+
+
+//-------------------------------------------------
+// s100_vi0_w - vectored interrupt 0
+//-------------------------------------------------
+
+void s100_wunderbus_device::s100_vi0_w(int state)
+{
+ m_pic->ir0_w(state);
+}
+
+
+//-------------------------------------------------
+// s100_vi1_w - vectored interrupt 1
+//-------------------------------------------------
+
+void s100_wunderbus_device::s100_vi1_w(int state)
+{
+ m_pic->ir1_w(state);
+}
+
+
+//-------------------------------------------------
+// s100_vi2_w - vectored interrupt 2
+//-------------------------------------------------
+
+void s100_wunderbus_device::s100_vi2_w(int state)
+{
+ m_pic->ir2_w(state);
+}
+
+
+//-------------------------------------------------
+// s100_sinp_r - I/O read
+//-------------------------------------------------
+
+UINT8 s100_wunderbus_device::s100_sinp_r(address_space &space, offs_t offset)
+{
+ UINT8 address = (m_7c->read() & 0x3e) << 2;
+ if ((offset & 0xf8) != address) return 0;
+
+ UINT8 data = 0;
+
+ if ((offset & 0x07) < 7)
+ {
+ switch (m_group)
+ {
+ case 0:
+ switch (offset & 0x07)
+ {
+ case 0: // DAISY 0 IN (STATUS)
+ /*
+
+ bit description
+
+ 0 End of Ribbon
+ 1 Paper Out
+ 2 Cover Open
+ 3 Paper Feed Ready
+ 4 Carriage Ready
+ 5 Print Wheel Ready
+ 6 Check
+ 7 Printer Ready
+
+ */
+ break;
+
+ case 1: // Switch/Parallel port flags
+ /*
+
+ bit description
+
+ 0 FLAG1
+ 1 FLAG2
+ 2 10A S6
+ 3 10A S5
+ 4 10A S4
+ 5 10A S3
+ 6 10A S2
+ 7 10A S1
+
+ */
+
+ data = BITSWAP8(m_10a->read(),0,1,2,3,4,5,6,7) & 0xfc;
+ break;
+
+ case 2: // R.T. Clock IN/RESET CLK. Int.
+ /*
+
+ bit description
+
+ 0 1990 Data Out
+ 1 1990 TP
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+
+ */
+
+ data |= m_rtc->data_out_r();
+ data |= m_rtc->tp_r() << 1;
+
+ // reset clock interrupt
+ m_rtc_tp = 0;
+ m_pic->ir7_w(m_rtc_tp);
+ break;
+
+ case 3: // Parallel data IN
+ break;
+
+ case 4: // 8259 0 register
+ case 5: // 8259 1 register
+ data = m_pic->read(space, offset & 0x01);
+ break;
+
+ case 6: // not used
+ break;
+ }
+ break;
+
+ case 1:
+ data = m_ace1->ins8250_r(space, offset & 0x07);
+ break;
+
+ case 2:
+ data = m_ace2->ins8250_r(space, offset & 0x07);
+ break;
+
+ case 3:
+ data = m_ace3->ins8250_r(space, offset & 0x07);
+ break;
+ }
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// s100_sout_w - I/O write
+//-------------------------------------------------
+
+void s100_wunderbus_device::s100_sout_w(address_space &space, offs_t offset, UINT8 data)
+{
+ UINT8 address = (m_7c->read() & 0x3e) << 2;
+ if ((offset & 0xf8) != address) return;
+
+ if ((offset & 0x07) == 7)
+ {
+ m_group = data & 0x03;
+ }
+ else
+ {
+ switch (m_group)
+ {
+ case 0:
+ switch (offset & 0x07)
+ {
+ case 0: // DAISY 0 OUT
+ /*
+
+ bit description
+
+ 0 Data Bit 9
+ 1 Data Bit 10
+ 2 Data Bit 11
+ 3 Data Bit 12
+ 4 Paper Feed Strobe
+ 5 Carriage Strobe
+ 6 Print Wheel Strobe
+ 7 Restore
+
+ */
+ break;
+
+ case 1: // DAISY 1 OUT
+ /*
+
+ bit description
+
+ 0 Data Bit 1
+ 1 Data Bit 2
+ 2 Data Bit 3
+ 3 Data Bit 4
+ 4 Data Bit 5
+ 5 Data Bit 6
+ 6 Data Bit 7
+ 7 Data Bit 8
+
+ */
+ break;
+
+ case 2: // R.T. Clock OUT
+ /*
+
+ bit description
+
+ 0 1990 Data In
+ 1 1990 Clk
+ 2 1990 C0
+ 3 1990 C1
+ 4 1990 C2
+ 5 1990 STB
+ 6 Ribbon Lift
+ 7 Select
+
+ */
+
+ m_rtc->data_in_w(BIT(data, 0));
+ m_rtc->clk_w(BIT(data, 1));
+ m_rtc->c0_w(BIT(data, 2));
+ m_rtc->c1_w(BIT(data, 3));
+ m_rtc->c2_w(BIT(data, 4));
+ m_rtc->stb_w(BIT(data, 5));
+ break;
+
+ case 3: // Par. data OUT
+ break;
+
+ case 4: // 8259 0 register
+ case 5: // 8259 1 register
+ m_pic->write(space, offset & 0x01, data);
+ break;
+
+ case 6: // Par. port cntrl.
+ /*
+
+ bit description
+
+ 0 POE
+ 1 _RST1
+ 2 _RST2
+ 3 _ATTN1
+ 4 _ATTN2
+ 5
+ 6
+ 7
+
+ */
+ break;
+ }
+ break;
+
+ case 1:
+ m_ace1->ins8250_w(space, offset & 0x07, data);
+ break;
+
+ case 2:
+ m_ace2->ins8250_w(space, offset & 0x07, data);
+ break;
+
+ case 3:
+ m_ace3->ins8250_w(space, offset & 0x07, data);
+ break;
+ }
+ }
+}