summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/psx/sio.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/cpu/psx/sio.c')
-rw-r--r--src/emu/cpu/psx/sio.c114
1 files changed, 40 insertions, 74 deletions
diff --git a/src/emu/cpu/psx/sio.c b/src/emu/cpu/psx/sio.c
index 24e12972f24..d9394403dfe 100644
--- a/src/emu/cpu/psx/sio.c
+++ b/src/emu/cpu/psx/sio.c
@@ -39,7 +39,13 @@ psxsio1_device::psxsio1_device(const machine_config &mconfig, const char *tag, d
psxsio_device::psxsio_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) :
device_t(mconfig, type, name, tag, owner, clock, shortname, source),
- m_irq_handler(*this)
+ m_status(SIO_STATUS_TX_EMPTY | SIO_STATUS_TX_RDY),
+ m_rxd(1),
+ m_irq_handler(*this),
+ m_sck_handler(*this),
+ m_txd_handler(*this),
+ m_dtr_handler(*this),
+ m_rts_handler(*this)
{
}
@@ -51,16 +57,15 @@ void psxsio_device::device_post_load()
void psxsio_device::device_start()
{
m_irq_handler.resolve_safe();
+ m_sck_handler.resolve_safe();
+ m_txd_handler.resolve_safe();
+ m_dtr_handler.resolve_safe();
+ m_rts_handler.resolve_safe();
m_timer = timer_alloc( 0 );
- m_status = SIO_STATUS_TX_EMPTY | SIO_STATUS_TX_RDY;
m_mode = 0;
m_control = 0;
m_baud = 0;
- m_tx = 0;
- m_rx = 0;
- m_tx_prev = 0;
- m_rx_prev = 0;
m_rx_data = 0;
m_tx_data = 0;
m_rx_shift = 0;
@@ -72,30 +77,13 @@ void psxsio_device::device_start()
save_item( NAME( m_mode ) );
save_item( NAME( m_control ) );
save_item( NAME( m_baud ) );
- save_item( NAME( m_tx ) );
- save_item( NAME( m_rx ) );
- save_item( NAME( m_tx_prev ) );
- save_item( NAME( m_rx_prev ) );
+ save_item( NAME( m_rxd ) );
save_item( NAME( m_rx_data ) );
save_item( NAME( m_tx_data ) );
save_item( NAME( m_rx_shift ) );
save_item( NAME( m_tx_shift ) );
save_item( NAME( m_rx_bits ) );
save_item( NAME( m_tx_bits ) );
-
- deviceCount = 0;
-
- for( device_t *device = first_subdevice(); device != NULL; device = device->next() )
- {
- psxsiodev_device *psxsiodev = dynamic_cast<psxsiodev_device *>(device);
- if( psxsiodev != NULL )
- {
- devices[ deviceCount++ ] = psxsiodev;
- psxsiodev->m_psxsio = this;
- }
- }
-
- input_update();
}
void psxsio_device::sio_interrupt()
@@ -149,22 +137,6 @@ void psxsio_device::sio_timer_adjust()
m_timer->adjust( n_time );
}
-void psxsio_device::output( int data, int mask )
-{
- int new_outputdata = ( m_outputdata & ~mask ) | ( data & mask );
- int new_mask = m_outputdata ^ new_outputdata;
-
- if( new_mask != 0 )
- {
- m_outputdata = new_outputdata;
-
- for( int i = 0; i < deviceCount; i++ )
- {
- devices[ i ]->data_in( m_outputdata, new_mask );
- }
- }
-}
-
void psxsio_device::device_timer(emu_timer &timer, device_timer_id tid, int param, void *ptr)
{
verboselog( machine(), 2, "sio tick\n" );
@@ -188,19 +160,20 @@ void psxsio_device::device_timer(emu_timer &timer, device_timer_id tid, int para
if( m_tx_bits != 0 )
{
- m_tx = ( m_tx & ~PSX_SIO_OUT_DATA ) | ( ( m_tx_shift & 1 ) * PSX_SIO_OUT_DATA );
+ if( type() == PSX_SIO0 )
+ {
+ m_sck_handler(0);
+ }
+
+ m_txd_handler( m_tx_shift & 1 );
m_tx_shift >>= 1;
m_tx_bits--;
if( type() == PSX_SIO0 )
{
- m_tx &= ~PSX_SIO_OUT_CLOCK;
- output( m_tx, PSX_SIO_OUT_CLOCK | PSX_SIO_OUT_DATA );
- m_tx |= PSX_SIO_OUT_CLOCK;
+ m_sck_handler(1);
}
- output( m_tx, PSX_SIO_OUT_CLOCK | PSX_SIO_OUT_DATA );
-
if( m_tx_bits == 0 &&
( m_control & SIO_CONTROL_TX_IENA ) != 0 )
{
@@ -210,7 +183,7 @@ void psxsio_device::device_timer(emu_timer &timer, device_timer_id tid, int para
if( m_rx_bits != 0 )
{
- m_rx_shift = ( m_rx_shift >> 1 ) | ( ( ( m_rx & PSX_SIO_IN_DATA ) / PSX_SIO_IN_DATA ) << 7 );
+ m_rx_shift = ( m_rx_shift >> 1 ) | ( m_rxd << 7 );
m_rx_bits--;
if( m_rx_bits == 0 )
@@ -265,31 +238,33 @@ WRITE32_MEMBER( psxsio_device::write )
verboselog( machine(), 1, "psx_sio_w reset\n" );
m_status |= SIO_STATUS_TX_EMPTY | SIO_STATUS_TX_RDY;
m_status &= ~( SIO_STATUS_RX_RDY | SIO_STATUS_OVERRUN | SIO_STATUS_IRQ );
+ m_irq_handler(0);
// toggle DTR to reset controllers, Star Ocean 2, at least, requires it
// the precise mechanism of the reset is unknown
// maybe it's related to the bottom 2 bits of control which are usually set
- output( m_tx ^ PSX_SIO_OUT_DTR, PSX_SIO_OUT_DTR );
+ m_dtr_handler(0);
+ m_dtr_handler(1);
+
+ m_tx_bits = 0;
+ m_rx_bits = 0;
+ m_txd_handler(1);
}
if( ( m_control & SIO_CONTROL_IACK ) != 0 )
{
verboselog( machine(), 1, "psx_sio_w iack\n" );
m_status &= ~( SIO_STATUS_IRQ );
m_control &= ~( SIO_CONTROL_IACK );
+ m_irq_handler(0);
}
if( ( m_control & SIO_CONTROL_DTR ) != 0 )
{
- m_tx |= PSX_SIO_OUT_DTR;
+ m_dtr_handler(0);
}
else
{
- m_tx &= ~PSX_SIO_OUT_DTR;
+ m_dtr_handler(1);
}
-
- output( m_tx, PSX_SIO_OUT_DTR );
-
- m_tx_prev = m_tx;
-
}
break;
case 3:
@@ -362,33 +337,24 @@ READ32_MEMBER( psxsio_device::read )
return data;
}
-void psxsio_device::input_update()
+WRITE_LINE_MEMBER(psxsio_device::write_rxd)
{
- int data = 0;
+ m_rxd = state;
+}
- for( int i = 0; i < deviceCount; i++ )
+WRITE_LINE_MEMBER(psxsio_device::write_dsr)
+{
+ if (state)
{
- data |= devices[ i ]->m_dataout;
+ m_status &= ~SIO_STATUS_DSR;
}
-
- int mask = data ^ m_rx;
-
- verboselog( machine(), 1, "input_update( %s, %02x, %02x )\n", tag(), mask, data );
-
- m_rx = data;
-
- if( ( m_rx & PSX_SIO_IN_DSR ) != 0 )
+ else if ((m_status & SIO_STATUS_DSR) == 0)
{
m_status |= SIO_STATUS_DSR;
- if( ( m_rx_prev & PSX_SIO_IN_DSR ) == 0 &&
- ( m_control & SIO_CONTROL_DSR_IENA ) != 0 )
+
+ if( ( m_control & SIO_CONTROL_DSR_IENA ) != 0 )
{
sio_interrupt();
}
}
- else
- {
- m_status &= ~SIO_STATUS_DSR;
- }
- m_rx_prev = m_rx;
}