Esempio n. 1
0
static TIMER_CALLBACK( dma8257_timerproc )
{
	const device_config *device = (const device_config *)ptr;
	dma8257_t *dma8257 = get_safe_token(device);
	int i, channel = 0, rr;
	int done;

	rr = DMA_MODE_ROTPRIO(dma8257->mode) ? dma8257->rr : 0;
	for (i = 0; i < DMA8257_NUM_CHANNELS; i++)
	{
		channel = (i + rr) % DMA8257_NUM_CHANNELS;
		if ((dma8257->status & (1 << channel)) == 0)
			if (dma8257->mode & dma8257->drq & (1 << channel))
				break;
	}
	done = dma8257_do_operation(device, channel);

	dma8257->rr = (channel + 1) & 0x03;

	if (done)
	{
		dma8257->drq    &= ~(0x01 << channel);
		dma8257_update_status(device);
  		if (!(DMA_MODE_AUTOLOAD(dma8257->mode) && channel==2)) {
			if (DMA_MODE_TCSTOP(dma8257->mode)) {
				dma8257->mode &= ~(0x01 << channel);
			}
		}
	}
}
Esempio n. 2
0
void i8257_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
	switch (id)
	{
		case TIMER_OPERATION:
		{
			int i, channel = 0, rr;
			int done;

			rr = DMA_MODE_ROTPRIO(m_mode) ? m_rr : 0;
			for (i = 0; i < I8257_NUM_CHANNELS; i++)
			{
				channel = (i + rr) % I8257_NUM_CHANNELS;
				if ((m_status & (1 << channel)) == 0)
				{
					if (m_mode & m_drq & (1 << channel))
					{
						break;
					}
				}
			}
			done = i8257_do_operation(channel);

			m_rr = (channel + 1) & 0x03;

			if (done)
			{
				m_drq &= ~(0x01 << channel);
				i8257_update_status();
				if (!(DMA_MODE_AUTOLOAD(m_mode) && channel==2))
				{
					if (DMA_MODE_TCSTOP(m_mode))
					{
						m_mode &= ~(0x01 << channel);
					}
				}
			}
			break;
		}

		case TIMER_MSBFLIP:
			m_msb ^= 1;
			break;

		case TIMER_DRQ_SYNC:
		{
			int channel = param >> 1;
			int state = param & 0x01;

			/* normalize state */
			if (state)
			{
				m_drq |= 0x01 << channel;
				m_address[channel] =  m_registers[channel * 2];
				m_count[channel] =  m_registers[channel * 2 + 1] & 0x3FFF;
				m_rwmode[channel] =  m_registers[channel * 2 + 1] >> 14;
				/* clear channel TC */
				m_status &= ~(0x01 << channel);
			}
			else
				m_drq &= ~(0x01 << channel);

			i8257_update_status();
			break;
		}
	}
Esempio n. 3
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;
}
Esempio n. 4
0
static int dma8257_do_operation(const device_config *device, int channel)
{
	dma8257_t *dma8257 = get_safe_token(device);
	int done;
	UINT8 data;
	UINT8 mode;

	mode = dma8257->rwmode[channel];
	if (dma8257->count[channel] == 0x0000)
	{
		dma8257->status |=  (0x01 << channel);
		if (dma8257->intf->out_tc[channel])
			dma8257->intf->out_tc[channel](device, 0, ASSERT_LINE);
	}
	switch(mode) {
	case 1:
		if (dma8257->intf->memory_read!=NULL) {
			data = dma8257->intf->memory_read(device, dma8257->address[channel]);
		} else {
			data = 0;
			logerror("8257: No memory read function defined.\n");
		}
		if (dma8257->intf->channel_write[channel]!=NULL) {
			dma8257->intf->channel_write[channel](device, 0, data);
		} else {
			logerror("8257: No channel write function for channel %d defined.\n",channel);
		}

		dma8257->address[channel]++;
		dma8257->count[channel]--;
		done = (dma8257->count[channel] == 0xFFFF);
		break;

	case 2:
		if (dma8257->intf->channel_read[channel]!=NULL) {
			data = dma8257->intf->channel_read[channel](device, 0);
		} else {
			data = 0;
			logerror("8257: No channel read function for channel %d defined.\n",channel);
		}

		if (dma8257->intf->memory_write!=NULL) {
			dma8257->intf->memory_write(device, dma8257->address[channel], data);
		} else {
			logerror("8257: No memory write function defined.\n");
		}
		dma8257->address[channel]++;
		dma8257->count[channel]--;
		done = (dma8257->count[channel] == 0xFFFF);
		break;
	case 0: /* verify */
		dma8257->address[channel]++;
		dma8257->count[channel]--;
		done = (dma8257->count[channel] == 0xFFFF);
		break;
	default:
		fatalerror("dma8257_do_operation: invalid mode!\n");
		break;
	}
	if (done)
	{
		if ((channel==2) && DMA_MODE_AUTOLOAD(dma8257->mode)) {
			/* in case of autoload at the end channel 3 info is */
			/* copied to channel 2 info                         */
			dma8257->registers[4] = dma8257->registers[6];
			dma8257->registers[5] = dma8257->registers[7];
		}
		if (dma8257->intf->out_tc[channel])
			dma8257->intf->out_tc[channel](device, 0, CLEAR_LINE);
	}
	return done;
}