Пример #1
0
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 );
  }
}
Пример #2
0
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;
}
Пример #3
0
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 );
}