static void head_load( upd_fdc *f ) { event_remove_type( head_event ); if( f->head_load ) { /* head already loaded */ if( f->cmd->id == UPD_CMD_READ_DATA || f->cmd->id == UPD_CMD_SCAN ) start_read_data( f ); else if( f->cmd->id == UPD_CMD_READ_ID ) start_read_id( f ); else if( f->cmd->id == UPD_CMD_READ_DIAG ) { fdd_wait_index_hole( f->current_drive ); /* start reading from index hole */ start_read_diag( f ); } else if( f->cmd->id == UPD_CMD_WRITE_DATA ) start_write_data( f ); else if( f->cmd->id == UPD_CMD_WRITE_ID ) { fdd_wait_index_hole( f->current_drive ); /* start writing from index hole */ start_write_id( f ); } } else { fdd_head_load( f->current_drive, 1 ); f->head_load = 1; event_add_with_data( tstates + f->hld_time * machine_current->timings.processor_speed / 1000, fdc_event, f ); } }
static void upd_fdc_event( libspectrum_dword last_tstates GCC_UNUSED, int event, void *user_data ) { upd_fdc *f = user_data; if( event == timeout_event ) { f->status_register[0] |= UPD_FDC_ST0_INT_ABNORM; f->status_register[1] |= UPD_FDC_ST1_OVERRUN; cmd_result( f ); return; } if( event == head_event ) { fdd_head_load( f->current_drive, 0 ); f->head_load = 0; return; } if( f->read_id ) { if( f->cmd->id == UPD_CMD_READ_DATA ) { start_read_data( f ); } else if( f->cmd->id == UPD_CMD_READ_ID ) { start_read_id( f ); } else if( f->cmd->id == UPD_CMD_READ_DIAG ) { start_read_diag( f ); } else if( f->cmd->id == UPD_CMD_WRITE_DATA ) { start_write_data( f ); } } else if( f->main_status & 0x03 ) { /* seek/recalibrate active */ seek_step( f, 0 ); } else if( f->cmd->id == UPD_CMD_READ_DATA || f->cmd->id == UPD_CMD_SCAN ) { start_read_data( f ); } else if( f->cmd->id == UPD_CMD_READ_ID ) { start_read_id( f ); } else if( f->cmd->id == UPD_CMD_READ_DIAG ) { fdd_wait_index_hole( f->current_drive ); /* start reading from index hole */ start_read_diag( f ); } else if( f->cmd->id == UPD_CMD_WRITE_DATA ) { start_write_data( f ); } else if( f->cmd->id == UPD_CMD_WRITE_ID ) { fdd_wait_index_hole( f->current_drive ); /* start writing from index hole */ start_write_id( f ); } return; }
static void wd_fdc_type_iii( wd_fdc *f ) { int i; fdd_t *d = f->current_drive; event_remove_type( fdc_event ); if( !f->read_id && ( f->type == WD1773 || f->type == FD1793 || f->type == WD2797) ) { if( !disk_ready( f ) ) { f->status_register &= ~WD_FDC_SR_BUSY; f->state = WD_FDC_STATE_NONE; wd_fdc_set_intrq( f ); return; } if( !f->hlt ) { event_add_with_data( tstates + 5 * machine_current->timings.processor_speed / 1000, fdc_event, f ); return; } } if( f->state == WD_FDC_STATE_WRITETRACK ) { /* ----WRITE TRACK---- */ if( d->wrprot ) { f->status_register |= WD_FDC_SR_WRPROT; f->status_register &= ~WD_FDC_SR_BUSY; f->state = WD_FDC_STATE_NONE; wd_fdc_set_intrq( f ); return; } f->status_register &= ~WD_FDC_SR_WRPROT; f->data_offset = 0; fdd_wait_index_hole( d ); wd_fdc_set_datarq( f ); } else if( f->state == WD_FDC_STATE_READTRACK ) { /* ----READ TRACK---- */ fdd_wait_index_hole( d ); wd_fdc_set_datarq( f ); } else { /* ----READID---- */ if( !f->read_id ) { f->read_id = 1; f->rev = 5; f->id_mark = WD_FDC_AM_NONE; } if( f->id_mark == WD_FDC_AM_NONE ) { while( f->rev ) { i = d->disk.i >= d->disk.bpt ? 0 : d->disk.i; /* start position */ read_id( f ); i = d->disk.bpt ? ( d->disk.i - i ) * 200 / d->disk.bpt : 200; if( i > 0 ) { event_add_with_data( tstates + i * /* i * 1/20 revolution */ machine_current->timings.processor_speed / 1000, fdc_event, f ); return; } else if( f->id_mark != WD_FDC_AM_NONE ) break; } if( f->id_mark == WD_FDC_AM_NONE ) { f->state = WD_FDC_STATE_NONE; f->status_register |= WD_FDC_SR_RNF; f->status_register &= ~WD_FDC_SR_BUSY; wd_fdc_set_intrq( f ); f->read_id = 0; return; } } f->read_id = 0; f->data_offset = 0; wd_fdc_set_datarq( f ); } event_remove_type( timeout_event ); event_add_with_data( tstates + 2 * 20 * /* 2 revolutions: 2 * 200 / 1000 */ machine_current->timings.processor_speed / 100, timeout_event, f ); }