summaryrefslogblamecommitdiffstatshomepage
path: root/src/emu/bus/s100/wunderbus.c
blob: 5195fbbf1a4bfab4bf7beeca9ba86d4a3b315edb (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11

                               








                                                                       
                      






                                                                            



                             


                                
                             






























                                                                            
                            

 



                                                   


                                    


                                                                        
                                                                    
                   









                                                   


                                                                        
                                                                    
                   









                                                   


                                                                        
                                                                    
                   



                  
                                              

                                                                

                         

                                                   







                                                    
                                       


         





                                                   
                                                                                                            


                                                                     






                                                                                           
                                                                           














                                                                                           
                                                                                                                         














































































































                                                                                                                             
                                                                                                          




                                                   


                                   









                                                   










                                                   
 





                                                   
                            








                                                   
                            








                                                   
                            






                                                   
                                                                             
 
                                                   













                                                      
                                                       
 







                                                             
 
                                  




                                                             
                                                       
 







                                                  
 
                                  
 
                                                                                      




                                                                
                                                       
 







                                                         
 
                                  





                                                            
                                                       






                                                   
                                                                         







                                           
                                                                       


                              
                                                                       


                              
                                                                       











                                                   
                                                                                        
 
                                                   















                                               
                                                       
 







                                                              
 
                                  




                                              
                                                       
 







                                                      
 
                                  




                                                 
                                                       
 







                                                        
 
                                  

                                                               




                                                           






                                                  
                                                                         




                                                   
                                                       
 







                                                  
 
                                  




                                      
                                                                      


                              
                                                                      


                              
                                                                      



                              
// license:BSD-3-Clause
// copyright-holders:Curt Coder
/**********************************************************************

    Morrow Designs Wunderbus I/O card emulation

    Copyright MESS Team.
    Visit http://mamedev.org for licensing and usage restrictions.

**********************************************************************/

#include "wunderbus.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->int_w(state);
}


//-------------------------------------------------
//  ins8250_interface ace1_intf
//-------------------------------------------------

static ins8250_interface ace1_intf =
{
	DEVCB_DEVICE_LINE_MEMBER(RS232_A_TAG, serial_port_device, tx),
	DEVCB_DEVICE_LINE_MEMBER(RS232_A_TAG, rs232_port_device, dtr_w),
	DEVCB_DEVICE_LINE_MEMBER(RS232_A_TAG, rs232_port_device, rts_w),
	DEVCB_DEVICE_LINE_MEMBER(I8259A_TAG, pic8259_device, ir3_w),
	DEVCB_NULL,
	DEVCB_NULL
};


//-------------------------------------------------
//  ins8250_interface ace2_intf
//-------------------------------------------------

static ins8250_interface ace2_intf =
{
	DEVCB_DEVICE_LINE_MEMBER(RS232_B_TAG, serial_port_device, tx),
	DEVCB_DEVICE_LINE_MEMBER(RS232_B_TAG, rs232_port_device, dtr_w),
	DEVCB_DEVICE_LINE_MEMBER(RS232_B_TAG, rs232_port_device, rts_w),
	DEVCB_DEVICE_LINE_MEMBER(I8259A_TAG, pic8259_device, ir4_w),
	DEVCB_NULL,
	DEVCB_NULL
};


//-------------------------------------------------
//  ins8250_interface ace3_intf
//-------------------------------------------------

static ins8250_interface ace3_intf =
{
	DEVCB_DEVICE_LINE_MEMBER(RS232_C_TAG, serial_port_device, tx),
	DEVCB_DEVICE_LINE_MEMBER(RS232_C_TAG, rs232_port_device, dtr_w),
	DEVCB_DEVICE_LINE_MEMBER(RS232_C_TAG, rs232_port_device, rts_w),
	DEVCB_DEVICE_LINE_MEMBER(I8259A_TAG, pic8259_device, ir5_w),
	DEVCB_NULL,
	DEVCB_NULL
};


static DEVICE_INPUT_DEFAULTS_START( terminal )
	DEVICE_INPUT_DEFAULTS( "TERM_FRAME", 0x0f, 0x0d ) // 110
	DEVICE_INPUT_DEFAULTS( "TERM_FRAME", 0x30, 0x20 ) // 8N2
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_INS8250_ADD(INS8250_1_TAG, ace1_intf, XTAL_18_432MHz/10)
	MCFG_INS8250_ADD(INS8250_2_TAG, ace2_intf, XTAL_18_432MHz/10)
	MCFG_INS8250_ADD(INS8250_3_TAG, ace3_intf, XTAL_18_432MHz/10)

	MCFG_RS232_PORT_ADD(RS232_A_TAG, default_rs232_devices, "serial_terminal")
	MCFG_SERIAL_OUT_RX_HANDLER(DEVWRITELINE(INS8250_1_TAG, ins8250_uart_device, rx_w))
	MCFG_RS232_OUT_DCD_HANDLER(DEVWRITELINE(INS8250_1_TAG, ins8250_uart_device, dcd_w))
	MCFG_RS232_OUT_DSR_HANDLER(DEVWRITELINE(INS8250_1_TAG, ins8250_uart_device, dsr_w))
	MCFG_RS232_OUT_RI_HANDLER(DEVWRITELINE(INS8250_1_TAG, ins8250_uart_device, ri_w))
	MCFG_RS232_OUT_CTS_HANDLER(DEVWRITELINE(INS8250_1_TAG, ins8250_uart_device, cts_w))
	MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS("serial_terminal", terminal)

	MCFG_RS232_PORT_ADD(RS232_B_TAG, default_rs232_devices, NULL)
	MCFG_SERIAL_OUT_RX_HANDLER(DEVWRITELINE(INS8250_2_TAG, ins8250_uart_device, rx_w))
	MCFG_RS232_OUT_DCD_HANDLER(DEVWRITELINE(INS8250_2_TAG, ins8250_uart_device, dcd_w))
	MCFG_RS232_OUT_DSR_HANDLER(DEVWRITELINE(INS8250_2_TAG, ins8250_uart_device, dsr_w))
	MCFG_RS232_OUT_RI_HANDLER(DEVWRITELINE(INS8250_2_TAG, ins8250_uart_device, ri_w))
	MCFG_RS232_OUT_CTS_HANDLER(DEVWRITELINE(INS8250_2_TAG, ins8250_uart_device, cts_w))

	MCFG_RS232_PORT_ADD(RS232_C_TAG, default_rs232_devices, NULL)
	MCFG_SERIAL_OUT_RX_HANDLER(DEVWRITELINE(INS8250_3_TAG, ins8250_uart_device, rx_w))
	MCFG_RS232_OUT_DCD_HANDLER(DEVWRITELINE(INS8250_3_TAG, ins8250_uart_device, dcd_w))
	MCFG_RS232_OUT_DSR_HANDLER(DEVWRITELINE(INS8250_3_TAG, ins8250_uart_device, dsr_w))
	MCFG_RS232_OUT_RI_HANDLER(DEVWRITELINE(INS8250_3_TAG, ins8250_uart_device, ri_w))
	MCFG_RS232_OUT_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;
		}
	}
}