void handle_command(struct ide_state *ide, UINT8 command) { /* implicitly clear interrupts here */ clear_interrupt(ide); ide->command = command; switch (command) { case IDE_COMMAND_READ_MULTIPLE: case IDE_COMMAND_READ_MULTIPLE_ONCE: LOGPRINT(("IDE Read multiple: C=%d H=%d S=%d LBA=%d count=%d\n", ide->cur_cylinder, ide->cur_head, ide->cur_sector, lba_address(ide), ide->sector_count)); /* reset the buffer */ ide->buffer_offset = 0; ide->sectors_until_int = 1; ide->dma_active = 0; /* start the read going */ read_first_sector(ide); break; case IDE_COMMAND_READ_MULTIPLE_BLOCK: LOGPRINT(("IDE Read multiple block: C=%d H=%d S=%d LBA=%d count=%d\n", ide->cur_cylinder, ide->cur_head, ide->cur_sector, lba_address(ide), ide->sector_count)); /* reset the buffer */ ide->buffer_offset = 0; ide->sectors_until_int = 1; ide->dma_active = 0; /* start the read going */ read_first_sector(ide); break; case IDE_COMMAND_READ_DMA: LOGPRINT(("IDE Read multiple DMA: C=%d H=%d S=%d LBA=%d count=%d\n", ide->cur_cylinder, ide->cur_head, ide->cur_sector, lba_address(ide), ide->sector_count)); /* reset the buffer */ ide->buffer_offset = 0; ide->sectors_until_int = ide->sector_count; ide->dma_active = 1; /* start the read going */ if (ide->bus_master_command & 1) read_first_sector(ide); break; case IDE_COMMAND_WRITE_MULTIPLE: LOGPRINT(("IDE Write multiple: C=%d H=%d S=%d LBA=%d count=%d\n", ide->cur_cylinder, ide->cur_head, ide->cur_sector, lba_address(ide), ide->sector_count)); /* reset the buffer */ ide->buffer_offset = 0; ide->sectors_until_int = 1; ide->dma_active = 0; /* mark the buffer ready */ ide->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", ide->cur_cylinder, ide->cur_head, ide->cur_sector, lba_address(ide), ide->sector_count)); /* reset the buffer */ ide->buffer_offset = 0; ide->sectors_until_int = 1; ide->dma_active = 0; /* mark the buffer ready */ ide->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", ide->cur_cylinder, ide->cur_head, ide->cur_sector, lba_address(ide), ide->sector_count)); /* reset the buffer */ ide->buffer_offset = 0; ide->sectors_until_int = ide->sector_count; ide->dma_active = 1; /* start the read going */ if (ide->bus_master_command & 1) { read_buffer_from_dma(ide); continue_write(ide); } break; case IDE_COMMAND_SECURITY_UNLOCK: LOGPRINT(("IDE Security Unlock\n")); /* reset the buffer */ ide->buffer_offset = 0; ide->sectors_until_int = 0; ide->dma_active = 0; /* mark the buffer ready */ ide->status |= IDE_STATUS_BUFFER_READY; signal_interrupt(ide); break; case IDE_COMMAND_GET_INFO: LOGPRINT(("IDE Read features\n")); /* reset the buffer */ ide->buffer_offset = 0; ide->sector_count = 1; /* build the features page */ memcpy(ide->buffer, ide->features, sizeof(ide->buffer)); /* indicate everything is ready */ ide->status |= IDE_STATUS_BUFFER_READY; ide->status |= IDE_STATUS_SEEK_COMPLETE; /* and clear the busy adn error flags */ ide->status &= ~IDE_STATUS_ERROR; ide->status &= ~IDE_STATUS_BUSY; /* clear the error too */ ide->error = IDE_ERROR_NONE; /* signal an interrupt */ signal_delayed_interrupt(ide, MINIMUM_COMMAND_TIME, 1); break; case IDE_COMMAND_SET_CONFIG: LOGPRINT(("IDE Set configuration (%d heads, %d sectors)\n", ide->cur_head + 1, ide->sector_count)); ide->num_sectors = ide->sector_count; ide->num_heads = ide->cur_head + 1; /* signal an interrupt */ signal_interrupt(ide); break; case IDE_COMMAND_UNKNOWN_F9: /* only used by Killer Instinct AFAICT */ LOGPRINT(("IDE unknown command (F9)\n")); /* signal an interrupt */ signal_interrupt(ide); break; case IDE_COMMAND_SET_FEATURES: LOGPRINT(("IDE Set features (%02X %02X %02X %02X %02X)\n", ide->precomp_offset, ide->sector_count & 0xff, ide->cur_sector, ide->cur_cylinder & 0xff, ide->cur_cylinder >> 8)); /* signal an interrupt */ signal_delayed_interrupt(ide, MINIMUM_COMMAND_TIME, 0); break; case IDE_COMMAND_SET_BLOCK_COUNT: LOGPRINT(("IDE Set block count (%02X)\n", ide->sector_count)); ide->block_count = ide->sector_count; // judge dredd wants 'drive ready' on this command ide->status |= IDE_STATUS_DRIVE_READY; /* signal an interrupt */ signal_interrupt(ide); break; default: LOGPRINT(("IDE unknown command (%02X)\n", command)); #ifdef MAME_DEBUG { extern int debug_key_pressed; debug_key_pressed = 1; } #endif break; } }
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; } }