Example #1
0
static struct unix_proto_data *unix_data_alloc(void)
{
    struct unix_proto_data *upd;

    clr_irq();
    for (upd = unix_datas; upd <= last_unix_data; ++upd) {
	if (!upd->refcnt) {
	    /* unix domain socket not yet in itialised - bgm */
	    upd->refcnt = -1;
	    set_irq();
	    upd->socket = NULL;
	    upd->sockaddr_len = 0;
	    upd->sockaddr_un.sun_family = 0;

#if 0
	    upd->buf = NULL;
#endif

	    upd->bp_head = upd->bp_tail = 0;
	    upd->inode = NULL;
	    upd->peerupd = NULL;
	    upd->sem = 0;
	    return upd;
	}
    }
    set_irq();
    return NULL;
}
Example #2
0
void wangpc_wdc_device::wangpcbus_aiowc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data)
{
	if (sad(offset) && ACCESSING_BITS_0_7)
	{
		switch (offset & 0x7f)
		{
		case 0x02/2:
			// TODO command register
			break;

		case 0xfc/2:
			device_reset();
			break;

		case 0xfe/2:
			{
				bool irq = (m_irq == ASSERT_LINE);
				bool changed = ((m_option & 0x0e) != (data & 0x0e));

				if (irq && changed) set_irq(CLEAR_LINE);

				m_option = data & 0xff;

				if (irq && changed) set_irq(ASSERT_LINE);
			}
			break;
		}
	}
}
Example #3
0
void ide_controller_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
	switch(id)
	{
	case TID_DELAYED_INTERRUPT:
		status &= ~IDE_STATUS_BUSY;
		set_irq(ASSERT_LINE);
		break;

	case TID_DELAYED_INTERRUPT_BUFFER_READY:
		status &= ~IDE_STATUS_BUSY;
		status |= IDE_STATUS_BUFFER_READY;
		set_irq(ASSERT_LINE);
		break;

	case TID_RESET_CALLBACK:
		reset();
		break;

	case TID_SECURITY_ERROR_DONE:
		/* clear error state */
		status &= ~IDE_STATUS_ERROR;
		status |= IDE_STATUS_DRIVE_READY;
		break;

	case TID_READ_SECTOR_DONE_CALLBACK:
		read_sector_done();
		break;

	case TID_WRITE_SECTOR_DONE_CALLBACK:
		write_sector_done();
		break;
	}
}
Example #4
0
void ide_controller_device::write_sector_done()
{
	ide_device_interface *dev = slot[cur_drive]->dev();
	int lba = dev->lba_address(), count = 0;

	/* now do the write */
	count = dev->write_sector(lba, buffer);

	/* by default, mark the buffer ready and the seek complete */
	status |= IDE_STATUS_BUFFER_READY;
	status |= IDE_STATUS_SEEK_COMPLETE;

	/* and clear the busy adn error flags */
	status &= ~IDE_STATUS_ERROR;
	status &= ~IDE_STATUS_BUSY;

	/* if we succeeded, advance to the next sector and set the nice bits */
	if (count == 1)
	{
		/* advance the pointers, unless this is the last sector */
		/* Gauntlet: Dark Legacy checks to make sure we stop on the last sector */
		if (sector_count != 1)
			next_sector();

		/* clear the error value */
		error = IDE_ERROR_NONE;

		/* signal an interrupt */
		if (--sectors_until_int == 0 || sector_count == 1)
		{
			sectors_until_int = ((command == IDE_COMMAND_WRITE_MULTIPLE_BLOCK) ? block_count : 1);
			set_irq(ASSERT_LINE);
		}

		/* signal an interrupt if there's more data needed */
		if (sector_count > 0)
			sector_count--;
		if (sector_count == 0)
			status &= ~IDE_STATUS_BUFFER_READY;

		/* keep going for DMA */
		if (dma_active && sector_count != 0)
		{
			set_dmarq(1);
		}
	}

	/* if we got an error, we need to report it */
	else
	{
		/* set the error flag and the error */
		status |= IDE_STATUS_ERROR;
		error = IDE_ERROR_BAD_SECTOR;

		/* signal an interrupt */
		set_irq(ASSERT_LINE);
	}
}
Example #5
0
void ata_flash_pccard_device::process_command()
{
	m_buffer_size = IDE_DISK_SECTOR_SIZE;

	switch (m_command)
	{
	case IDE_COMMAND_TAITO_GNET_UNLOCK_1:
		//LOGPRINT(("IDE GNET Unlock 1\n"));

		m_sector_count = 1;
		m_status |= IDE_STATUS_DRDY;

		set_irq(ASSERT_LINE);
		break;

	case IDE_COMMAND_TAITO_GNET_UNLOCK_2:
		//LOGPRINT(("IDE GNET Unlock 2\n"));

		/* mark the buffer ready */
		m_status |= IDE_STATUS_DRQ;

		set_irq(ASSERT_LINE);
		break;

	case IDE_COMMAND_TAITO_GNET_UNLOCK_3:
		//LOGPRINT(("IDE GNET Unlock 3\n"));

		/* key check */
		if (m_feature == m_key[0] && m_sector_count == m_key[1] && m_sector_number == m_key[2] && m_cylinder_low == m_key[3] && m_cylinder_high == m_key[4])
		{
			m_gnetreadlock = 0;
		}
		else
		{
			m_status &= ~IDE_STATUS_DRDY;
		}

		set_irq(ASSERT_LINE);
		break;

	default:
		if (m_gnetreadlock)
		{
			m_status |= IDE_STATUS_ERR;
			m_error = IDE_ERROR_NONE;
			m_status &= ~IDE_STATUS_DRDY;
			break;
		}

		ide_hdd_device::process_command();
		break;
	}
}
Example #6
0
void ata_mass_storage_device::finished_command()
{
	switch (m_command)
	{
	case IDE_COMMAND_IDENTIFY_DEVICE:
		if (m_can_identify_device)
		{
			for( int w = 0; w < 256; w++ )
			{
				m_buffer[w * 2] = m_identify_buffer[ w ] & 0xff;
				m_buffer[(w * 2) + 1] = m_identify_buffer[ w ] >> 8;
			}

			m_status |= IDE_STATUS_DRQ;
		}
		else
		{
			m_status |= IDE_STATUS_ERR;
			m_error = IDE_ERROR_NONE;
		}

		set_irq(ASSERT_LINE);
		break;

	case IDE_COMMAND_SET_CONFIG:
		set_geometry(m_sector_count,(m_device_head & IDE_DEVICE_HEAD_HS) + 1);
		set_irq(ASSERT_LINE);
		break;

	case IDE_COMMAND_READ_SECTORS:
	case IDE_COMMAND_READ_SECTORS_NORETRY:
	case IDE_COMMAND_READ_MULTIPLE:
	case IDE_COMMAND_VERIFY_SECTORS:
	case IDE_COMMAND_VERIFY_SECTORS_NORETRY:
	case IDE_COMMAND_READ_DMA:
		finished_read();
		break;

	case IDE_COMMAND_WRITE_SECTORS:
	case IDE_COMMAND_WRITE_SECTORS_NORETRY:
	case IDE_COMMAND_WRITE_MULTIPLE:
	case IDE_COMMAND_WRITE_DMA:
		finished_write();
		break;

	case IDE_COMMAND_RECALIBRATE:
		set_irq(ASSERT_LINE);
		break;

	default:
		ata_hle_device::finished_command();
		break;
	}
Example #7
0
File: sched.c Project: Mellvik/elks
static void run_timer_list(void)
{
    register struct timer_list *timer;

    clr_irq();
    while ((timer = tl_list.tl_next) && timer->tl_expires <= jiffies) {
        detach_timer(timer);
        set_irq();
        timer->tl_function(timer->tl_data);
        clr_irq();
    }
    set_irq();
}
Example #8
0
void ym3802_device::transmit_clk()
{
	if(m_reg[REG_TCR] & 0x01) // Tx Enable
	{
		if(!m_tx_fifo.empty())
		{
			if (is_transmit_register_empty())
			{
				transmit_register_setup(m_tx_fifo.front());  // start to send first byte in FIFO
				m_tx_fifo.pop();                                // and remove it from the FIFO
				if(m_tx_fifo.empty())
					set_irq(IRQ_FIFOTX_EMPTY);
			}
		}
		/* if diserial has bits to send, make them so */
		if (!is_transmit_register_empty())
		{
			uint8_t data = transmit_register_get_data_bit();
			m_tx_busy = true;
			m_txd_handler(data);
		}
		if (m_tx_fifo.empty() && is_transmit_register_empty())
			m_tx_busy = false;
	}
}
Example #9
0
BOOL init_harddisk()
{
	set_irq(IRQ_HD, (u32)&do_harddisk_read);		/* 设置中断处理程序 */
	enable_irq(IRQ_HD);						        /* 通知8259A开启硬盘中断 */

    return TRUE;
}
Example #10
0
UINT16 wangpc_wdc_device::wangpcbus_iorc_r(address_space &space, offs_t offset, UINT16 mem_mask)
{
	UINT16 data = 0xffff;

	if (sad(offset))
	{
		switch (offset & 0x7f)
		{
		case 0x00/2:
			data = m_status;
			break;

		case 0x02/2:
			// TODO operation status register
			break;

		case 0x04/2:
			set_irq(CLEAR_LINE);
			break;

		case 0xfe/2:
			data = 0xff00 | (m_irq << 7) | OPTION_ID;
			break;
		}
	}

	return data;
}
Example #11
0
void wangpc_wdc_device::device_reset()
{
	m_status = 0;
	m_option = 0;

	set_irq(CLEAR_LINE);
}
Example #12
0
void el2_3c503_device::eop_w(int state) {
	if((m_regs.streg & 0x08) && (state == ASSERT_LINE)) {
		m_regs.streg |= 0x10;
		m_regs.streg &= ~0x08;
		if(!(m_regs.gacfr & 0x40)) set_irq(ASSERT_LINE);
	}
}
Example #13
0
void init_keyboard(void)
{
	set_irq(IRQ_KEYBOARD, (u32)&do_keyboard);		/* 设置中断处理程序 */
	enable_irq(IRQ_KEYBOARD);						/* 通知8259A开启键盘中断 */
	init_queue(&kb_queue);						    /* 初始化缓存区队列 */

	b_shift_l = FALSE;
	b_shift_r = FALSE;
	b_leading_e0 = FALSE;
}
Example #14
0
void UPD765A::reset()
{
	shift_to_idle();
//	CANCEL_EVENT();
	phase_id = drq_id = lost_id = result7_id = -1;
	seek_id[0] = seek_id[1] = seek_id[2] = seek_id[3] = -1;
	
	set_irq(false);
	set_drq(false);
}
Example #15
0
void UPD765A::close_disk(int drv)
{
	if(drv < MAX_DRIVE && disk[drv]->inserted) {
		disk[drv]->close();
#ifdef _FDC_DEBUG_LOG
		emu->out_debug_log("FDC: Disk Ejected (Drive=%d)\n", drv);
#endif
		if(raise_irq_when_media_changed) {
			fdc[drv].result = (drv & DRIVE_MASK) | ST0_AI;
			set_irq(true);
		}
	}
}
Example #16
0
void UPD765A::open_disk(int drv, _TCHAR path[], int bank)
{
	if(drv < MAX_DRIVE) {
		disk[drv]->open(path, bank);
		if(disk[drv]->changed) {
#ifdef _FDC_DEBUG_LOG
			emu->out_debug_log("FDC: Disk Changed (Drive=%d)\n", drv);
#endif
			if(raise_irq_when_media_changed) {
				fdc[drv].result = (drv & DRIVE_MASK) | ST0_AI;
				set_irq(true);
			}
		}
	}
}
Example #17
0
void ym3802_device::midi_clk()
{
	if(m_midi_counter_base > 1)  // counter is not guaranteed to work if set to 0 or 1.
	{
		if(m_midi_counter == 0)
		{
			m_midi_counter = m_midi_counter_base;  // reload timer
			if(m_reg[REG_IMR] & 0x08)  // if IRQ1 is set to MIDI clock detect
				set_irq(IRQ_MIDI_CLK);
			if(m_click_counter_base != 0)
			{
				m_click_counter--;
				if(m_click_counter == 0)
				{
					m_click_counter = m_click_counter_base;
					if(!(m_reg[REG_IMR] & 0x08))  // if IRQ1 is set to click counter
						set_irq(IRQ_CLICK);
				}
			}
		}
		else
			m_midi_counter--;
	}
}
Example #18
0
void UPD765A::shift_to_result7_event()
{
#ifdef UPD765A_NO_ST1_EN_OR_FOR_RESULT7
	// for NEC PC-9801 (XANADU)
	result &= ~(ST1_EN | ST1_OR);
#endif
	buffer[0] = (result & 0xf8) | (hdue & 7);
	buffer[1] = uint8(result >>  8);
	buffer[2] = uint8(result >> 16);
	buffer[3] = id[0];
	buffer[4] = id[1];
	buffer[5] = id[2];
	buffer[6] = id[3];
	set_irq(true);
	shift_to_result(7);
}
Example #19
0
void device_setup(void)
{
    register struct gendisk *p;

    chr_dev_init();
    blk_dev_init();

    set_irq();

    for (p = gendisk_head; p; p = p->next)
	setup_dev(p);

#ifdef CONFIG_BLK_DEV_RAM
    rd_load();
#endif

}
Example #20
0
UINT16 wangpc_mvc_device::wangpcbus_iorc_r(address_space &space, offs_t offset, UINT16 mem_mask)
{
	UINT16 data = 0xffff;

	if (sad(offset))
	{
		switch (offset & 0x7f)
		{
		case 0xfe/2:
			data = 0xff00 | (m_irq << 7) | OPTION_ID;

			set_irq(CLEAR_LINE);
			break;
		}
	}

	return data;
}
Example #21
0
void cdp1879_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
	advance_seconds();

	// comparator IRQ
	bool new_state = true;
	for (int i = R_CNT_SECONDS; i <= R_CNT_HOURS; i++)
	{
		if(m_regs[i] != m_regs[i + 6])
		{
			new_state = false;
			break;
		}
	}

	if (!m_comparator_state && new_state)  // positive-edge-triggered
		set_irq(7);

	m_comparator_state = new_state;
}
Example #22
0
void UPD765A::seek_event(int drv)
{
	int trk = fdc[drv].track;
	
	if(drv >= MAX_DRIVE) {
		fdc[drv].result = (drv & DRIVE_MASK) | ST0_SE | ST0_NR | ST0_AT;
	} else if(force_ready || disk[drv]->inserted) {
		fdc[drv].result = (drv & DRIVE_MASK) | ST0_SE;
	} else {
#ifdef UPD765A_NO_ST0_AT_FOR_SEEK
		// for NEC PC-100
		fdc[drv].result = (drv & DRIVE_MASK) | ST0_SE | ST0_NR;
#else
		fdc[drv].result = (drv & DRIVE_MASK) | ST0_SE | ST0_NR | ST0_AT;
#endif
	}
	set_irq(true);
	seekstat &= ~(1 << drv);
	
	// reset dsch flag
	disk[drv]->changed = false;
}
Example #23
0
void UPD765A::initialize()
{
	// initialize d88 handler
	for(int i = 0; i < 4; i++) {
		disk[i] = new DISK(emu);
	}
	
	// initialize fdc
	memset(fdc, 0, sizeof(fdc));
	memset(buffer, 0, sizeof(buffer));
	
	phase = prevphase = PHASE_IDLE;
	status = S_RQM;
	seekstat = 0;
	bufptr = buffer; // temporary
	phase_id = drq_id = lost_id = result7_id = -1;
	seek_id[0] = seek_id[1] = seek_id[2] = seek_id[3] = -1;
	no_dma_mode = false;
	motor_on = false;	// motor off
	force_ready = false;
	reset_signal = true;
	irq_masked = drq_masked = false;
	
	set_irq(false);
	set_drq(false);
#ifdef UPD765A_EXT_DRVSEL
	hdu = 0;
#else
	set_hdu(0);
#endif
	
	// index hole event
	if(outputs_index.count) {
		register_event(this, EVENT_INDEX, 4, true, NULL);
		prev_index = false;
	}
}
Example #24
0
void wangpc_mvc_device::device_reset()
{
	m_option = 0;

	set_irq(CLEAR_LINE);
}
Example #25
0
int wait_for_keypress(void)
{
    set_irq();
    return chq_getch(&ttys[0].inq, 0, 1);
}
Example #26
0
void gf1_device::update_volume_ramps()
{
	int x;

	for(x=0;x<32;x++)
	{
		if(!(m_voice[x].vol_ramp_ctrl & 0x01))  // if ramping is enabled
		{
			m_voice[x].vol_count++;
			if(m_voice[x].vol_count % volume_ramp_table[(m_voice[x].vol_ramp_rate & 0xc0)>>6] == 0)
			{
				// increase/decrease volume
				if(m_voice[x].vol_ramp_ctrl & 0x40)
				{
					//m_voice[x].current_vol = (m_voice[x].current_vol & 0xf000) | ((m_voice[x].current_vol & 0x0ff0) + ((m_voice[x].vol_ramp_rate & 0x0f)<<8));
					m_voice[x].current_vol -= ((m_voice[x].vol_ramp_rate & 0x3f) << 4);
					if(m_voice[x].current_vol <= (m_voice[x].vol_ramp_start << 8))  // end of ramp?
					{
						if(m_voice[x].vol_ramp_ctrl & 0x08)
						{
							if(m_voice[x].vol_ramp_ctrl & 0x10)
							{
								m_voice[x].vol_ramp_ctrl &= ~0x40; // change direction and continue
								m_voice[x].current_vol = (m_voice[x].vol_ramp_start << 8);
							}
							else
								m_voice[x].current_vol = (m_voice[x].vol_ramp_end << 8);
						}
						else
						{
							m_voice[x].vol_ramp_ctrl |= 0x01;  // stop volume ramp
							m_voice[x].current_vol = (m_voice[x].vol_ramp_start << 8);
						}
						if(m_voice[x].vol_ramp_ctrl & 0x20)
							set_irq(IRQ_VOLUME_RAMP,x);
					}
				}
				else
				{
					//m_voice[x].current_vol = (m_voice[x].current_vol & 0xf000) | ((m_voice[x].current_vol & 0x0ff0) - ((m_voice[x].vol_ramp_rate & 0x0f)<<8));
					m_voice[x].current_vol += ((m_voice[x].vol_ramp_rate & 0x3f) << 4);
					if(m_voice[x].current_vol >= (m_voice[x].vol_ramp_end << 8))  // end of ramp?
					{
						if(m_voice[x].vol_ramp_ctrl & 0x08)
						{
							if(m_voice[x].vol_ramp_ctrl & 0x10)
							{
								m_voice[x].vol_ramp_ctrl |= 0x40; // change direction and continue
								m_voice[x].current_vol = (m_voice[x].vol_ramp_end << 8);
							}
							else
								m_voice[x].current_vol = (m_voice[x].vol_ramp_start << 8);
						}
						else
						{
							m_voice[x].vol_ramp_ctrl |= 0x01;  // stop volume ramp
							m_voice[x].current_vol = (m_voice[x].vol_ramp_end << 8);
						}
						if(m_voice[x].vol_ramp_ctrl & 0x20)
							set_irq(IRQ_VOLUME_RAMP,x);
					}
				}
			}
		}
	}
Example #27
0
int wait_for_keypress(void)
{
    set_irq();
    return chq_wait_rd(&ttys[0].inq, 0);
}
Example #28
0
void ide_controller_device::handle_command(UINT8 _command)
{
	UINT8 key[5];
	ide_device_interface *dev = slot[cur_drive]->dev();

	/* implicitly clear interrupts & dmarq here */
	set_irq(CLEAR_LINE);
	set_dmarq(0);
	command = _command;
	switch (command)
	{
		case IDE_COMMAND_READ_MULTIPLE:
		case IDE_COMMAND_READ_MULTIPLE_NORETRY:
			LOGPRINT(("IDE Read multiple: C=%d H=%d S=%d LBA=%d count=%d\n",
				dev->cur_cylinder, dev->cur_head, dev->cur_sector, dev->lba_address(), sector_count));

			/* reset the buffer */
			buffer_offset = 0;
			sectors_until_int = 1;
			dma_active = 0;
			verify_only = 0;

			/* start the read going */
			read_first_sector();
			break;

		case IDE_COMMAND_READ_MULTIPLE_BLOCK:
			LOGPRINT(("IDE Read multiple block: C=%d H=%d S=%d LBA=%d count=%d\n",
				dev->cur_cylinder, dev->cur_head, dev->cur_sector, dev->lba_address(), sector_count));

			/* reset the buffer */
			buffer_offset = 0;
			sectors_until_int = 1;
			dma_active = 0;
			verify_only = 0;

			/* start the read going */
			read_first_sector();
			break;

		case IDE_COMMAND_VERIFY_MULTIPLE:
		case IDE_COMMAND_VERIFY_NORETRY:
			LOGPRINT(("IDE Read verify multiple with/without retries: C=%d H=%d S=%d LBA=%d count=%d\n",
				dev->cur_cylinder, dev->cur_head, dev->cur_sector, dev->lba_address(), sector_count));

			/* reset the buffer */
			buffer_offset = 0;
			sectors_until_int = 1;
			dma_active = 0;
			verify_only = 1;

			/* start the read going */
			read_first_sector();
			break;

		case IDE_COMMAND_READ_DMA:
			LOGPRINT(("IDE Read multiple DMA: C=%d H=%d S=%d LBA=%d count=%d\n",
				dev->cur_cylinder, dev->cur_head, dev->cur_sector, dev->lba_address(), sector_count));

			/* reset the buffer */
			buffer_offset = 0;
			sectors_until_int = sector_count;
			dma_active = 1;
			verify_only = 0;

			/* start the read going */
			read_first_sector();
			break;

		case IDE_COMMAND_WRITE_MULTIPLE:
		case IDE_COMMAND_WRITE_MULTIPLE_NORETRY:
			LOGPRINT(("IDE Write multiple: C=%d H=%d S=%d LBA=%d count=%d\n",
				dev->cur_cylinder, dev->cur_head, dev->cur_sector, dev->lba_address(), sector_count));

			/* reset the buffer */
			buffer_offset = 0;
			sectors_until_int = 1;
			dma_active = 0;

			/* mark the buffer ready */
			status |= IDE_STATUS_BUFFER_READY;
			break;

		case IDE_COMMAND_WRITE_MULTIPLE_BLOCK:
			LOGPRINT(("IDE Write multiple block: C=%d H=%d S=%d LBA=%d count=%d\n",
				dev->cur_cylinder, dev->cur_head, dev->cur_sector, dev->lba_address(), sector_count));

			/* reset the buffer */
			buffer_offset = 0;
			sectors_until_int = 1;
			dma_active = 0;

			/* mark the buffer ready */
			status |= IDE_STATUS_BUFFER_READY;
			break;

		case IDE_COMMAND_WRITE_DMA:
			LOGPRINT(("IDE Write multiple DMA: C=%d H=%d S=%d LBA=%d count=%d\n",
				dev->cur_cylinder, dev->cur_head, dev->cur_sector, dev->lba_address(), sector_count));

			/* reset the buffer */
			buffer_offset = 0;
			sectors_until_int = sector_count;
			dma_active = 1;

			/* start the read going */
			set_dmarq(1);
			break;

		case IDE_COMMAND_SECURITY_UNLOCK:
			LOGPRINT(("IDE Security Unlock\n"));

			/* reset the buffer */
			buffer_offset = 0;
			sectors_until_int = 0;
			dma_active = 0;

			/* mark the buffer ready */
			status |= IDE_STATUS_BUFFER_READY;
			set_irq(ASSERT_LINE);
			break;

		case IDE_COMMAND_GET_INFO:
			LOGPRINT(("IDE Read features\n"));

			/* reset the buffer */
			buffer_offset = 0;
			sector_count = 1;

			/* build the features page */
			memcpy(buffer, slot[cur_drive]->dev()->get_features(), sizeof(buffer));

			/* indicate everything is ready */
			status |= IDE_STATUS_BUFFER_READY;
			status |= IDE_STATUS_SEEK_COMPLETE;
			status |= IDE_STATUS_DRIVE_READY;

			/* and clear the busy adn error flags */
			status &= ~IDE_STATUS_ERROR;
			status &= ~IDE_STATUS_BUSY;

			/* clear the error too */
			error = IDE_ERROR_NONE;

			/* signal an interrupt */
			signal_delayed_interrupt(MINIMUM_COMMAND_TIME, 1);
			break;

		case IDE_COMMAND_DIAGNOSTIC:
			error = IDE_ERROR_DEFAULT;

			/* signal an interrupt */
			signal_delayed_interrupt(MINIMUM_COMMAND_TIME, 0);
			break;

		case IDE_COMMAND_RECALIBRATE:
			/* clear the error too */
			error = IDE_ERROR_NONE;
			/* signal an interrupt */
			signal_delayed_interrupt(MINIMUM_COMMAND_TIME, 0);
			break;

		case IDE_COMMAND_IDLE:
			/* clear the error too */
			error = IDE_ERROR_NONE;

			/* for timeout disabled value is 0 */
			sector_count = 0;
			/* signal an interrupt */
			set_irq(ASSERT_LINE);
			break;

		case IDE_COMMAND_SET_CONFIG:
			LOGPRINT(("IDE Set configuration (%d heads, %d sectors)\n", dev->cur_head + 1, sector_count));
			status &= ~IDE_STATUS_ERROR;
			error = IDE_ERROR_NONE;
			dev->set_geometry(sector_count,dev->cur_head + 1);

			/* signal an interrupt */
			signal_delayed_interrupt(MINIMUM_COMMAND_TIME, 0);
			break;

		case IDE_COMMAND_UNKNOWN_F9:
			/* only used by Killer Instinct AFAICT */
			LOGPRINT(("IDE unknown command (F9)\n"));

			/* signal an interrupt */
			set_irq(ASSERT_LINE);
			break;

		case IDE_COMMAND_SET_FEATURES:
			LOGPRINT(("IDE Set features (%02X %02X %02X %02X %02X)\n", precomp_offset, sector_count & 0xff, dev->cur_sector, dev->cur_cylinder & 0xff, dev->cur_cylinder >> 8));

			/* signal an interrupt */
			signal_delayed_interrupt(MINIMUM_COMMAND_TIME, 0);
			break;

		case IDE_COMMAND_SET_BLOCK_COUNT:
			LOGPRINT(("IDE Set block count (%02X)\n", sector_count));

			block_count = sector_count;
			// judge dredd wants 'drive ready' on this command
			status |= IDE_STATUS_DRIVE_READY;

			/* signal an interrupt */
			set_irq(ASSERT_LINE);
			break;

		case IDE_COMMAND_TAITO_GNET_UNLOCK_1:
			LOGPRINT(("IDE GNET Unlock 1\n"));

			sector_count = 1;
			status |= IDE_STATUS_DRIVE_READY;
			status &= ~IDE_STATUS_ERROR;
			set_irq(ASSERT_LINE);
			break;

		case IDE_COMMAND_TAITO_GNET_UNLOCK_2:
			LOGPRINT(("IDE GNET Unlock 2\n"));

			/* reset the buffer */
			buffer_offset = 0;
			sectors_until_int = 0;
			dma_active = 0;

			/* mark the buffer ready */
			status |= IDE_STATUS_BUFFER_READY;
			set_irq(ASSERT_LINE);
			break;

		case IDE_COMMAND_TAITO_GNET_UNLOCK_3:
			LOGPRINT(("IDE GNET Unlock 3\n"));

			/* key check */
			dev->read_key(key);
			if ((precomp_offset == key[0]) && (sector_count == key[1]) && (dev->cur_sector == key[2]) && (dev->cur_cylinder == (((UINT16)key[4]<<8)|key[3])))
			{
				gnetreadlock= 0;
			}

			/* update flags */
			status |= IDE_STATUS_DRIVE_READY;
			status &= ~IDE_STATUS_ERROR;
			set_irq(ASSERT_LINE);
			break;

		case IDE_COMMAND_SEEK:
			/*
			    cur_cylinder, cur_sector and cur_head
			    are all already set in this case so no need
			    so that implements actual seek
			*/
			/* clear the error too */
			error = IDE_ERROR_NONE;

			/* for timeout disabled value is 0 */
			sector_count = 0;
			/* signal an interrupt */
			set_irq(ASSERT_LINE);
			break;


		default:
			LOGPRINT(("IDE unknown command (%02X)\n", command));
			status |= IDE_STATUS_ERROR;
			error = IDE_ERROR_UNKNOWN_COMMAND;
			set_irq(ASSERT_LINE);
			//debugger_break(device->machine());
			break;
	}
}
Example #29
0
void ide_controller_device::read_sector_done()
{
	ide_device_interface *dev = slot[cur_drive]->dev();
	int lba = dev->lba_address(), count = 0;

	/* GNET readlock check */
	if (gnetreadlock) {
		status &= ~IDE_STATUS_ERROR;
		status &= ~IDE_STATUS_BUSY;
		return;
	}
	/* now do the read */
	count = dev->read_sector(lba, buffer);

	/* by default, mark the buffer ready and the seek complete */
	if (!verify_only)
		status |= IDE_STATUS_BUFFER_READY;
	status |= IDE_STATUS_SEEK_COMPLETE;

	/* and clear the busy and error flags */
	status &= ~IDE_STATUS_ERROR;
	status &= ~IDE_STATUS_BUSY;

	/* if we succeeded, advance to the next sector and set the nice bits */
	if (count == 1)
	{
		/* advance the pointers, unless this is the last sector */
		/* Gauntlet: Dark Legacy checks to make sure we stop on the last sector */
		if (sector_count != 1)
			next_sector();

		/* clear the error value */
		error = IDE_ERROR_NONE;

		/* signal an interrupt */
		if (!verify_only)
			sectors_until_int--;
		if (sectors_until_int == 0 || sector_count == 1)
		{
			sectors_until_int = ((command == IDE_COMMAND_READ_MULTIPLE_BLOCK) ? block_count : 1);
			set_irq(ASSERT_LINE);
		}

		/* handle DMA */
		if (dma_active)
			set_dmarq(1);

		/* if we're just verifying we can read the next sector */
		if (verify_only)
			read_buffer_empty();
	}

	/* if we got an error, we need to report it */
	else
	{
		/* set the error flag and the error */
		status |= IDE_STATUS_ERROR;
		error = IDE_ERROR_BAD_SECTOR;

		/* signal an interrupt */
		set_irq(ASSERT_LINE);
	}
}
Example #30
0
Virtio::Virtio(hw::PCI_Device& dev)
  : _pcidev(dev), _virtio_device_id(dev.product_id() + 0x1040)
{
  INFO("Virtio","Attaching to  PCI addr 0x%x",_pcidev.pci_addr());


  /** PCI Device discovery. Virtio std. §4.1.2  */

  /**
      Match vendor ID and Device ID : §4.1.2.2
  */
  if (_pcidev.vendor_id() != hw::PCI_Device::VENDOR_VIRTIO)
    panic("This is not a Virtio device");
  CHECK(true, "Vendor ID is VIRTIO");

  bool _STD_ID = _virtio_device_id >= 0x1040 and _virtio_device_id < 0x107f;
  bool _LEGACY_ID = _pcidev.product_id() >= 0x1000
    and _pcidev.product_id() <= 0x103f;

  CHECK(_STD_ID or _LEGACY_ID, "Device ID 0x%x is in a valid range (%s)",
        _pcidev.product_id(),
        _STD_ID ? ">= Virtio 1.0" : (_LEGACY_ID ? "Virtio LEGACY" : "INVALID"));

  assert(_STD_ID or _LEGACY_ID);

  /**
      Match Device revision ID. Virtio Std. §4.1.2.2
  */
  bool rev_id_ok = ((_LEGACY_ID and _pcidev.rev_id() == 0) or
                    (_STD_ID and _pcidev.rev_id() > 0));


  CHECK(rev_id_ok and version_supported(_pcidev.rev_id()),
        "Device Revision ID (0x%x) supported", _pcidev.rev_id());

  assert(rev_id_ok); // We'll try to continue if it's newer than supported.

  // Probe PCI resources and fetch I/O-base for device
  _pcidev.probe_resources();
  _iobase=_pcidev.iobase();

  CHECK(_iobase, "Unit has valid I/O base (0x%x)", _iobase);

  /** Device initialization. Virtio Std. v.1, sect. 3.1: */

  // 1. Reset device
  reset();
  INFO2("[*] Reset device");

  // 2. Set ACKNOWLEGE status bit, and
  // 3. Set DRIVER status bit

  hw::outp(_iobase + VIRTIO_PCI_STATUS,
           hw::inp(_iobase + VIRTIO_PCI_STATUS) |
           VIRTIO_CONFIG_S_ACKNOWLEDGE |
           VIRTIO_CONFIG_S_DRIVER);


  // THE REMAINING STEPS MUST BE DONE IN A SUBCLASS
  // 4. Negotiate features (Read, write, read)
  //    => In the subclass (i.e. Only the Nic driver knows if it wants a mac)
  // 5. @todo IF >= Virtio 1.0, set FEATURES_OK status bit
  // 6. @todo IF >= Virtio 1.0, Re-read Device Status to ensure features are OK
  // 7. Device specifig setup.

  // Where the standard isn't clear, we'll do our best to separate work
  // between this class and subclasses.

  //Fetch IRQ from PCI resource
  set_irq();

  CHECK(_irq, "Unit has IRQ %i", _irq);
  INFO("Virtio","Enabling IRQ Handler");
  enable_irq_handler();



  INFO("Virtio", "Initialization complete");

  // It would be nice if we new that all queues were the same size.
  // Then we could pass this size on to the device-specific constructor
  // But, it seems there aren't any guarantees in the standard.

  // @note this is "the Legacy interface" according to Virtio std. 4.1.4.8.
  // uint32_t queue_size = hw::inpd(_iobase + 0x0C);

  /* printf(queue_size > 0 and queue_size != PCI_WTF ?
     "\t [x] Queue Size : 0x%lx \n" :
     "\t [ ] No qeuue Size? : 0x%lx \n" ,queue_size); */

}