Пример #1
0
inline void am9517a_device::dma_read()
{
	offs_t offset = m_channel[m_current_channel].m_address;

	switch (MODE_TRANSFER_MASK)
	{
	case MODE_TRANSFER_VERIFY:
	case MODE_TRANSFER_WRITE:
		m_temp = m_channel[m_current_channel].m_in_ior_func(offset);
		break;

	case MODE_TRANSFER_READ:
		m_temp = m_in_memr_func(offset);
		break;
	}
}
Пример #2
0
void i8237_device::i8237_do_read()
{
	int channel = m_service_channel;

	switch( DMA_MODE_OPERATION( m_chan[ channel ].m_mode ) )
	{
	case DMA8237_WRITE_TRANSFER:
		m_temporary_data = m_chan[channel].m_in_ior_func(0);
		break;
	case DMA8237_READ_TRANSFER:
		m_temporary_data = m_in_memr_func(m_chan[ channel ].m_address);
		break;
	case DMA8237_VERIFY_TRANSFER:
	case DMA8237_ILLEGAL_TRANSFER:
		break;
	}
}
Пример #3
0
inline void am9517a_device::dma_write()
{
	offs_t offset = m_channel[m_current_channel].m_address;

	switch (MODE_TRANSFER_MASK)
	{
	case MODE_TRANSFER_VERIFY: {
		UINT8 v1 = m_in_memr_func(offset);
		if(0 && m_temp != v1)
			logerror("%s: verify error %02x vs. %02x\n", tag(), m_temp, v1);
		break;
	}

	case MODE_TRANSFER_WRITE:
		m_out_memw_func(offset, m_temp);
		break;

	case MODE_TRANSFER_READ:
		m_channel[m_current_channel].m_out_iow_func(offset, m_temp);
		break;
	}
}
Пример #4
0
void i8237_device::i8237_timerproc()
{
	/* Check if operation is disabled */
	if ( m_command & 0x04 )
	{
		return;
	}

	switch ( m_state )
	{

	case DMA8237_SI:
	{
		/* Make sure EOP is high */
		if ( !m_eop )
		{
			m_eop = 1;
			m_out_eop_func(m_eop ? ASSERT_LINE : CLEAR_LINE);
		}

		/* Check if a new DMA request has been received. */
		/* Bit 6 of the command register determines whether the DREQ signals are active
          high or active low. */
		UINT16 pending_request = ( ( m_command & 0x40 ) ? ~m_drq : m_drq ) & ~m_mask;

		if ( pending_request & 0x0f )
		{
			int prio_channel = 0;

			/* Determine the channel that should be serviced */
			int channel = ( m_command & 0x10 ) ? m_last_service_channel : 3;
			for ( int i = 0; i < 4; i++ )
			{
				if ( pending_request & ( 1 << channel ) )
				{
					prio_channel = channel;
				}
				channel = ( channel - 1 ) & 0x03;
			}

			/* Store the channel we will be servicing and go to the next state */
			m_service_channel = prio_channel;
			m_last_service_channel = prio_channel;

			m_hrq = 1;
			m_out_hrq_func(m_hrq);
			m_state = DMA8237_S0;

			m_timer->enable( true );
		}
		else if (m_command == 3 && (m_drq & 1))
		{
			/* Memory-to-memory transfers */
			m_hlda = 1;
			m_state = DMA8237_S0;
		}
		else
		{
			m_timer->enable( false );
		}
		break;
	}

	case DMA8237_S0:
		/* S0 is the first of the DMA service. We have requested a hold but are waiting
          for confirmation. */
		if ( m_hlda )
		{
			if ( DMA_MODE_TRANSFERMODE( m_chan[m_service_channel].m_mode ) == DMA8237_CASCADE_MODE )
			{
				/* Cascade Mode, set DACK */
				i8327_set_dack(m_service_channel);

				/* Wait until peripheral is done */
				m_state = DMA8237_SC;
			}
			else
			{
				if ( m_command & 0x01 )
				{
					/* Memory-to-memory transfers */
					m_state = DMA8237_S11;
				}
				else
				{
					/* Regular transfers */
					m_state = DMA8237_S1;
				}
			}
		}
		break;

	case DMA8237_SC:	/* Cascade mode, waiting until peripheral is done */
		if ( ! ( m_drq & ( 0x01 << m_service_channel ) ) )
		{
			m_hrq = 0;
			m_hlda = 0;
			m_out_hrq_func(m_hrq);
			m_state = DMA8237_SI;

			/* Clear DACK */
			i8327_set_dack(-1);
		}

		/* Not sure if this is correct, documentation is not clear */
		/* Check if EOP output needs to be asserted  */
		if ( m_status & ( 0x01 << m_service_channel ) )
		{
			m_eop = 0;
			m_out_eop_func(m_eop ? ASSERT_LINE : CLEAR_LINE);
		}
		break;

	case DMA8237_S1:	/* Output A8-A15 */
		m_state = DMA8237_S2;
		break;

	case DMA8237_S2:	/* Output A7-A0 */
		/* set DACK */
		i8327_set_dack(m_service_channel);

		/* Check for compressed timing */
		if ( m_command & 0x08 )
		{
			m_state = DMA8237_S4;
		}
		else
		{
			m_state = DMA8237_S3;
		}
		break;

	case DMA8237_S3:	/* Initiate read */
		i8237_do_read();
		m_state = DMA8237_S4;
		break;

	case DMA8237_S4:	/* Perform read/write */
		/* Perform read when in compressed timing mode */
		if ( m_command & 0x08 )
		{
			i8237_do_read();
		}

		/* Perform write */
		i8237_do_write();


		/* Advance */
		i8237_advance();

		{
			int channel = m_service_channel;

			switch( DMA_MODE_TRANSFERMODE( m_chan[channel].m_mode ) )
			{
			case DMA8237_DEMAND_MODE:
				/* Check for terminal count or EOP signal or DREQ begin de-asserted */
				if ( ( m_status & ( 0x01 << channel ) ) || !m_eop || !( m_drq & ( 0x01 << channel ) ) )
				{
					m_hrq = 0;
					m_hlda = 0;
					m_out_hrq_func(m_hrq);
					m_state = DMA8237_SI;
				}
				else
				{
					m_state = m_chan[channel].m_high_address_changed ? DMA8237_S1 : DMA8237_S2;
				}
				break;

			case DMA8237_SINGLE_MODE:
				m_hrq = 0;
				m_hlda = 0;
				m_out_hrq_func(m_hrq);
				m_state = DMA8237_SI;
				break;

			case DMA8237_BLOCK_MODE:
				/* Check for terminal count or EOP signal */
				if ( ( m_status & ( 0x01 << channel ) ) || !m_eop )
				{
					m_hrq = 0;
					m_hlda = 0;
					m_out_hrq_func(m_hrq);
					m_state = DMA8237_SI;
				}
				else
				{
					m_state = m_chan[channel].m_high_address_changed ? DMA8237_S1 : DMA8237_S2;
				}
				break;
			}

			/* Check if EOP output needs to be asserted */
			if ( m_status & ( 0x01 << channel ) )
			{
				m_eop = 0;
				m_out_eop_func(m_eop ? ASSERT_LINE : CLEAR_LINE);
			}
		}

		/* clear DACK */
		if ( m_state == DMA8237_SI )
		{
			i8327_set_dack(-1);
		}
		break;

	case DMA8237_S11: /* Output A8-A15 */

//      logerror("###### dma8237_timerproc %s: from %04x count=%x to %04x count=%x\n", tag(),
//              m_chan[0].m_address, m_chan[0].m_count,
//              m_chan[1].m_address, m_chan[1].m_count);

		// FIXME: this will copy bytes correct, but not 16 bit words
		m_temporary_data = m_in_memr_func(m_chan[0].m_address);
		m_out_memw_func(m_chan[1].m_address, m_temporary_data);

		m_service_channel = 0;

		/* Advance */
		i8237_advance();

		// advance destination channel as well
		m_chan[1].m_count--;
		m_chan[1].m_address++;

		if (m_chan[0].m_count == 0xFFFF || m_chan[1].m_count == 0xFFFF) {
			m_hrq = 0;
			m_hlda = 0;
			m_out_hrq_func(m_hrq);
			m_state = DMA8237_SI;
			m_status |= 3; // set TC for channel 0 and 1
			m_drq &= ~3; // clear drq for channel 0 and 1

		//  logerror("!!! dma8237_timerproc DMA8237_S11 %s: m_drq=%x m_command=%x\n", tag(), m_drq, m_command);
		}
		break;
	}
}
Пример #5
0
int i8257_device::i8257_do_operation(int channel)
{
	int done;
	UINT8 data;

	UINT8 mode = m_rwmode[channel];
	if (m_count[channel] == 0x0000)
	{
		m_status |=  (0x01 << channel);

		m_out_tc_func(ASSERT_LINE);
	}
	switch(mode) {
	case 1:
		if (!m_in_memr_func.isnull())
		{
			data = m_in_memr_func(m_address[channel]);
		}
		else
		{
			data = 0;
			logerror("8257: No memory read function defined.\n");
		}
		if (!m_out_iow_func[channel].isnull())
		{
			m_out_iow_func[channel](m_address[channel], data);
		}
		else
		{
			logerror("8257: No channel write function for channel %d defined.\n",channel);
		}

		m_address[channel]++;
		m_count[channel]--;
		done = (m_count[channel] == 0xFFFF);
		break;

	case 2:
		if (!m_in_ior_func[channel].isnull())
		{
			data = m_in_ior_func[channel](m_address[channel]);
		}
		else
		{
			data = 0;
			logerror("8257: No channel read function for channel %d defined.\n",channel);
		}

		if (!m_out_memw_func.isnull())
		{
			m_out_memw_func(m_address[channel], data);
		}
		else
		{
			logerror("8257: No memory write function defined.\n");
		}
		m_address[channel]++;
		m_count[channel]--;
		done = (m_count[channel] == 0xFFFF);
		break;
	case 0: /* verify */
		m_address[channel]++;
		m_count[channel]--;
		done = (m_count[channel] == 0xFFFF);
		break;
	default:
		fatalerror("i8257_do_operation: invalid mode!\n");
		break;
	}
	if (done)
	{
		if ((channel==2) && DMA_MODE_AUTOLOAD(m_mode))
		{
			/* in case of autoload at the end channel 3 info is */
			/* copied to channel 2 info                         */
			m_registers[4] = m_registers[6];
			m_registers[5] = m_registers[7];
		}

		m_out_tc_func(CLEAR_LINE);
	}
	return done;
}