static void read_sector_done(int which) { struct ide_state *ide = &idestate[which]; int lba = lba_address(ide), count = 0; /* now do the read */ if (ide->disk) count = hard_disk_read(ide->disk, lba, 1, ide->buffer); /* by default, mark the buffer ready and the seek complete */ if (!ide->verify_only) ide->status |= IDE_STATUS_BUFFER_READY; ide->status |= IDE_STATUS_SEEK_COMPLETE; /* and clear the busy and error flags */ ide->status &= ~IDE_STATUS_ERROR; ide->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 (ide->sector_count != 1) next_sector(ide); /* clear the error value */ ide->error = IDE_ERROR_NONE; /* signal an interrupt */ if (!ide->verify_only) ide->sectors_until_int--; if (ide->sectors_until_int == 0 || ide->sector_count == 1) { ide->sectors_until_int = ((ide->command == IDE_COMMAND_READ_MULTIPLE_BLOCK) ? ide->block_count : 1); signal_interrupt(ide); } /* handle DMA */ if (ide->dma_active) write_buffer_to_dma(ide); /* if we're just verifying or if we DMA'ed the data, we can read the next sector */ if (ide->verify_only || ide->dma_active) continue_read(ide); } /* if we got an error, we need to report it */ else { /* set the error flag and the error */ ide->status |= IDE_STATUS_ERROR; ide->error = IDE_ERROR_BAD_SECTOR; ide->bus_master_status |= IDE_BUSMASTER_STATUS_ERROR; ide->bus_master_status &= ~IDE_BUSMASTER_STATUS_ACTIVE; /* signal an interrupt */ signal_interrupt(ide); } }
static void delayed_interrupt_buffer_ready(int which) { struct ide_state *ide = &idestate[which]; ide->status &= ~IDE_STATUS_BUSY; ide->status |= IDE_STATUS_BUFFER_READY; signal_interrupt(ide); }
void test3() { char buf[BUFSIZE]; ssize_t n; if( signal_interrupt( SIGINT, sig_handler ) == SIG_ERR ) { printf("failed to install signal handler!\n"); exit(-1); } // if /* sleep(10); // interrupt */ n = read(STDIN_FILENO, buf, BUFSIZE); // interrupt //!! different from normal behavior printf( "%zd\n", n ); /* pause(); // interrupt */ printf("errno = %s\n", strerror(errno)); }
static void delayed_interrupt(int which) { struct ide_state *ide = &idestate[which]; ide->status &= ~IDE_STATUS_BUSY; signal_interrupt(ide); }
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; } }