Index: machines/specplus3.c
===================================================================
--- machines/specplus3.c	(revision 5113)
+++ machines/specplus3.c	(working copy)
@@ -62,7 +62,7 @@
 static int specplus3_reset( void );
 
 upd_fdc *specplus3_fdc;
-static upd_fdc_drive specplus3_drives[ SPECPLUS3_NUM_DRIVES ];
+static fdd_t specplus3_drives[ SPECPLUS3_NUM_DRIVES ];
 
 static int ui_drive_is_available( void );
 static const fdd_params_t *ui_drive_get_params_a( void );
@@ -140,7 +140,6 @@
 specplus3_765_init( void )
 {
   int i;
-  upd_fdc_drive *d;
 
   specplus3_fdc = upd_fdc_alloc_fdc( UPD765A, UPD_CLOCK_4MHZ );
   /*!!!! the plus3 only use the US0 pin to select drives,
@@ -151,12 +150,11 @@
   specplus3_fdc->drive[3] = &specplus3_drives[ 1 ];
 
   for( i = 0; i < SPECPLUS3_NUM_DRIVES; i++ ) {
-    d = &specplus3_drives[ i ];
-    d->disk.flag = DISK_FLAG_PLUS3_CPC;
+    specplus3_drives[ i ].disk.flag = DISK_FLAG_PLUS3_CPC;
   }
 					/* builtin drive 1 head 42 track */
-  fdd_init( &specplus3_drives[ 0 ].fdd, FDD_SHUGART, &fdd_params[ 1 ], 0 );
-  fdd_init( &specplus3_drives[ 1 ].fdd, FDD_SHUGART, NULL, 0 );	/* drive geometry 'autodetect' */
+  fdd_init( &specplus3_drives[ 0 ], FDD_SHUGART, &fdd_params[ 1 ], 0 );
+  fdd_init( &specplus3_drives[ 1 ], FDD_SHUGART, NULL, 0 );	/* drive geometry 'autodetect' */
   specplus3_fdc->set_intrq = NULL;
   specplus3_fdc->reset_intrq = NULL;
   specplus3_fdc->set_datarq = NULL;
@@ -165,8 +163,7 @@
   specplus3_765_update_fdd();
 
   for( i = 0; i < SPECPLUS3_NUM_DRIVES; i++ ) {
-    ui_drives[ i ].fdd = &specplus3_drives[ i ].fdd;
-    ui_drives[ i ].disk = &specplus3_drives[ i ].disk;
+    ui_drives[ i ].fdd = &specplus3_drives[ i ];
     ui_media_drive_register( &ui_drives[ i ] );
   }
 }
@@ -178,10 +175,10 @@
 
   upd_fdc_master_reset( specplus3_fdc );
   dt = &fdd_params[ option_enumerate_diskoptions_drive_plus3a_type() + 1 ];	/* +1 => there is no `Disabled' */
-  fdd_init( &specplus3_drives[ 0 ].fdd, FDD_SHUGART, dt, 1 );
+  fdd_init( &specplus3_drives[ 0 ], FDD_SHUGART, dt, 1 );
 
   dt = &fdd_params[ option_enumerate_diskoptions_drive_plus3b_type() ];
-  fdd_init( &specplus3_drives[ 1 ].fdd, dt->enabled ? FDD_SHUGART : FDD_TYPE_NONE, dt, 1 );
+  fdd_init( &specplus3_drives[ 1 ], dt->enabled ? FDD_SHUGART : FDD_TYPE_NONE, dt, 1 );
 }
 
 static int
@@ -302,8 +299,8 @@
   if( machine_current->capabilities &&
       LIBSPECTRUM_MACHINE_CAPABILITY_PLUS3_DISK ) {
 
-    fdd_motoron( &specplus3_drives[0].fdd, b & 0x08 );
-    fdd_motoron( &specplus3_drives[1].fdd, b & 0x08 );
+    fdd_motoron( &specplus3_drives[0], b & 0x08 );
+    fdd_motoron( &specplus3_drives[1], b & 0x08 );
 
     ui_statusbar_update( UI_STATUSBAR_ITEM_DISK,
 			 b & 0x08 ? UI_STATUSBAR_STATE_ACTIVE :
@@ -405,7 +402,7 @@
 fdd_t *
 specplus3_get_fdd( specplus3_drive_number which )
 {
-  return &( specplus3_drives[ which ].fdd );
+  return &( specplus3_drives[ which ] );
 }
 
 static int
@@ -432,7 +429,7 @@
 ui_drive_inserted( const ui_media_drive_info_t *drive, int new )
 {
   if( new )
-    disk_preformat( drive->disk );		/* pre-format disk for +3 */
+    disk_preformat( &drive->fdd->disk );		/* pre-format disk for +3 ??? */
   return 0;
 }
 
Index: peripherals/disk/beta.c
===================================================================
--- peripherals/disk/beta.c	(revision 5113)
+++ peripherals/disk/beta.c	(working copy)
@@ -69,12 +69,8 @@
 libspectrum_word beta_pc_mask;
 libspectrum_word beta_pc_value;
 
-static int beta_index_pulse = 0;
-
-static int index_event;
-
 static wd_fdc *beta_fdc;
-static wd_fdc_drive beta_drives[ BETA_NUM_DRIVES ];
+static fdd_t beta_drives[ BETA_NUM_DRIVES ];
 static ui_media_drive_info_t beta_ui_drives[ BETA_NUM_DRIVES ];
 
 static const periph_port_t beta_ports[] = {
@@ -98,8 +94,6 @@
 static void beta_enabled_snapshot( libspectrum_snap *snap );
 static void beta_from_snapshot( libspectrum_snap *snap );
 static void beta_to_snapshot( libspectrum_snap *snap );
-static void beta_event_index( libspectrum_dword last_tstates, int type,
-			      void *user_data );
 
 static module_info_t beta_module_info = {
 
@@ -140,9 +134,9 @@
 {
   if( beta_fdc->current_drive != &beta_drives[ i & 0x03 ] ) {
     if( beta_fdc->current_drive != NULL )
-      fdd_select( &beta_fdc->current_drive->fdd, 0 );
+      fdd_select( beta_fdc->current_drive, 0 );
     beta_fdc->current_drive = &beta_drives[ i & 0x03 ];
-    fdd_select( &beta_fdc->current_drive->fdd, 1 );
+    fdd_select( beta_fdc->current_drive, 1 );
   }
 }
 
@@ -150,7 +144,7 @@
 beta_init( void )
 {
   int i;
-  wd_fdc_drive *d;
+  fdd_t *d;
 
   beta_fdc = wd_fdc_alloc_fdc( FD1793, 0, WD_FLAG_BETA128 );
   beta_fdc->current_drive = NULL;
@@ -157,7 +151,7 @@
 
   for( i = 0; i < BETA_NUM_DRIVES; i++ ) {
     d = &beta_drives[ i ];
-    fdd_init( &d->fdd, FDD_SHUGART, NULL, 0 );	/* drive geometry 'autodetect' */
+    fdd_init( d, FDD_SHUGART, NULL, 0 );	/* drive geometry 'autodetect' */
     d->disk.flag = DISK_FLAG_NONE;
   }
   beta_select_drive( 0 );
@@ -168,8 +162,6 @@
   beta_fdc->set_datarq = NULL;
   beta_fdc->reset_datarq = NULL;
 
-  index_event = event_register( beta_event_index, "Beta disk index" );
-
   module_register( &beta_module_info );
 
   beta_memory_source = memory_source_register( "Betadisk" );
@@ -179,9 +171,7 @@
   periph_register( PERIPH_TYPE_BETA128, &beta_peripheral );
 
   for( i = 0; i < BETA_NUM_DRIVES; i++ ) {
-    d = &beta_drives[ i ];
-    beta_ui_drives[ i ].fdd = &d->fdd;
-    beta_ui_drives[ i ].disk = &d->disk;
+    beta_ui_drives[ i ].fdd = &beta_drives[ i ];
     ui_media_drive_register( &beta_ui_drives[ i ] );
   }
 }
@@ -190,10 +180,8 @@
 beta_reset( int hard_reset GCC_UNUSED )
 {
   int i;
-  wd_fdc_drive *d;
+  fdd_t *d;
 
-  event_remove_type( index_event );
-
   if( !(periph_is_active( PERIPH_TYPE_BETA128 ) ||
         periph_is_active( PERIPH_TYPE_BETA128_PENTAGON ) ||
         periph_is_active( PERIPH_TYPE_BETA128_PENTAGON_LATE )) ) {
@@ -206,14 +194,14 @@
 
   beta_pc_mask = 0xff00;
   beta_pc_value = 0x3d00;
-  
+
   wd_fdc_master_reset( beta_fdc );
 
   for( i = 0; i < BETA_NUM_DRIVES; i++ ) {
     d = &beta_drives[ i ];
 
-    d->index_pulse = 0;
-    d->index_interrupt = 0;
+//    d->index_pulse = 0;
+    d->index_interrupt = 0; /* ?? */
   }
 
   if( !beta_builtin ) {
@@ -251,7 +239,6 @@
 
   beta_select_drive( 0 );
   machine_current->memory_map();
-  beta_event_index( 0, 0, NULL );
 
   ui_statusbar_update( UI_STATUSBAR_ITEM_DISK, UI_STATUSBAR_STATE_INACTIVE );
 }
@@ -340,7 +327,7 @@
   beta_select_drive( b & 0x03 );
   /* 0x08 = block hlt, normally set */
   wd_fdc_set_hlt( beta_fdc, ( ( b & 0x08 ) ? 1 : 0 ) );
-  fdd_set_head( &beta_fdc->current_drive->fdd, ( ( b & 0x10 ) ? 0 : 1 ) );
+  fdd_set_head( beta_fdc->current_drive, ( ( b & 0x10 ) ? 0 : 1 ) );
   /* 0x20 = density, reset = FM, set = MFM */
   beta_fdc->dden = b & 0x20 ? 1 : 0;
 
@@ -394,34 +381,10 @@
 fdd_t *
 beta_get_fdd( beta_drive_number which )
 {
-  return &( beta_drives[ which ].fdd );
+  return &( beta_drives[ which ] );
 }
 
 static void
-beta_event_index( libspectrum_dword last_tstates, int type, void *user_data )
-{
-  int next_tstates;
-  int i;
-
-  beta_index_pulse = !beta_index_pulse;
-  for( i = 0; i < BETA_NUM_DRIVES; i++ ) {
-    wd_fdc_drive *d = &beta_drives[ i ];
-
-    d->index_pulse = beta_index_pulse;
-/* disabled, until we have better timing emulation,
- * to avoid interrupts while reading/writing data */
-    if( !beta_index_pulse && d->index_interrupt ) {
-      wd_fdc_set_intrq( beta_fdc );
-      d->index_interrupt = 0;
-    }
-  }
-  next_tstates = ( beta_index_pulse ? 10 : 190 ) *
-    machine_current->timings.processor_speed / 1000;
-
-  event_add( last_tstates + next_tstates, index_event );
-}
-
-static void
 beta_enabled_snapshot( libspectrum_snap *snap )
 {
   if( libspectrum_snap_beta_active( snap ) )
Index: peripherals/disk/disciple.c
===================================================================
--- peripherals/disk/disciple.c	(revision 5113)
+++ peripherals/disk/disciple.c	(working copy)
@@ -65,12 +65,8 @@
 int disciple_available = 0;
 int disciple_active = 0;
 
-static int disciple_index_pulse;
-
-static int index_event;
-
 static wd_fdc *disciple_fdc;
-static wd_fdc_drive disciple_drives[ DISCIPLE_NUM_DRIVES ];
+static fdd_t disciple_drives[ DISCIPLE_NUM_DRIVES ];
 static ui_media_drive_info_t disciple_ui_drives[ DISCIPLE_NUM_DRIVES ];
 
 static libspectrum_byte *disciple_ram;
@@ -78,8 +74,6 @@
 
 static void disciple_reset( int hard_reset );
 static void disciple_memory_map( void );
-static void disciple_event_index( libspectrum_dword last_tstates, int type,
-				  void *user_data );
 static void disciple_activate( void );
 
 static module_info_t disciple_module_info = {
@@ -167,18 +161,18 @@
 disciple_init( void )
 {
   int i;
-  wd_fdc_drive *d;
+  fdd_t *d;
 
   disciple_fdc = wd_fdc_alloc_fdc( WD1770, 0, WD_FLAG_NONE );
 
   for( i = 0; i < DISCIPLE_NUM_DRIVES; i++ ) {
     d = &disciple_drives[ i ];
-    fdd_init( &d->fdd, FDD_SHUGART, NULL, 0 );
+    fdd_init( d, FDD_SHUGART, NULL, 0 );
     d->disk.flag = DISK_FLAG_NONE;
   }
 
   disciple_fdc->current_drive = &disciple_drives[ 0 ];
-  fdd_select( &disciple_drives[ 0 ].fdd, 1 );
+  fdd_select( &disciple_drives[ 0 ], 1 );
   disciple_fdc->dden = 1;
   disciple_fdc->set_intrq = NULL;
   disciple_fdc->reset_intrq = NULL;
@@ -186,10 +180,8 @@
   disciple_fdc->reset_datarq = NULL;
   disciple_fdc->iface = NULL;
 
-  index_event = event_register( disciple_event_index, "DISCiPLE index" );
+  module_register( &disciple_module_info );
 
-  module_register( &disciple_module_info );
-  
   disciple_memory_source_rom = memory_source_register( "DISCiPLE ROM" );
   disciple_memory_source_ram = memory_source_register( "DISCiPLE RAM" );
 
@@ -208,9 +200,7 @@
   periph_register( PERIPH_TYPE_DISCIPLE, &disciple_periph );
 
   for( i = 0; i < DISCIPLE_NUM_DRIVES; i++ ) {
-    d = &disciple_drives[ i ];
-    disciple_ui_drives[ i ].fdd = &d->fdd;
-    disciple_ui_drives[ i ].disk = &d->disk;
+    disciple_ui_drives[ i ].fdd = &disciple_drives[ i ];
     ui_media_drive_register( &disciple_ui_drives[ i ] );
   }
 }
@@ -219,13 +209,10 @@
 disciple_reset( int hard_reset )
 {
   int i;
-  wd_fdc_drive *d;
 
   disciple_active = 0;
   disciple_available = 0;
 
-  event_remove_type( index_event );
-
   if( !periph_is_active( PERIPH_TYPE_DISCIPLE ) ) {
     return;
   }
@@ -249,9 +236,8 @@
 
   disciple_available = 1;
   disciple_active = 1;
-  disciple_index_pulse = 0;
 
-  disciple_memswap = 0;
+//  disciple_memswap = 0;
   /* TODO: add support for 16 KiB ROM images. */
   /* disciple_rombank = 0; */
 
@@ -261,19 +247,13 @@
   wd_fdc_master_reset( disciple_fdc );
 
   for( i = 0; i < DISCIPLE_NUM_DRIVES; i++ ) {
-    d = &disciple_drives[ i ];
-
-    d->index_pulse = 0;
-    d->index_interrupt = 0;
-
     ui_media_drive_update_menus( &disciple_ui_drives[ i ],
                                  UI_MEDIA_DRIVE_UPDATE_ALL );
   }
 
   disciple_fdc->current_drive = &disciple_drives[ 0 ];
-  fdd_select( &disciple_drives[ 0 ].fdd, 1 );
+  fdd_select( &disciple_drives[ 0 ], 1 );
   machine_current->memory_map();
-  disciple_event_index( 0, index_event, NULL );
 
   ui_statusbar_update( UI_STATUSBAR_ITEM_DISK, UI_STATUSBAR_STATE_INACTIVE );
 }
@@ -368,14 +348,14 @@
   side = ( b & 0x02 ) ? 1 : 0;
 
   for( i = 0; i < DISCIPLE_NUM_DRIVES; i++ ) {
-    fdd_set_head( &disciple_drives[ i ].fdd, side );
-    fdd_select( &disciple_drives[ i ].fdd, drive == i );
+    fdd_set_head( &disciple_drives[ i ], side );
+    fdd_select( &disciple_drives[ i ], drive == i );
   }
 
   if( disciple_fdc->current_drive != &disciple_drives[ drive ] ) {
-    if( disciple_fdc->current_drive->fdd.motoron ) {
+    if( disciple_fdc->current_drive->motoron ) {
       for (i = 0; i < DISCIPLE_NUM_DRIVES; i++ ) {
-        fdd_motoron( &disciple_drives[ i ].fdd, drive == i );
+        fdd_motoron( &disciple_drives[ i ], drive == i );
       }
     }
     disciple_fdc->current_drive = &disciple_drives[ drive ];
@@ -451,32 +431,10 @@
 fdd_t *
 disciple_get_fdd( disciple_drive_number which )
 {
-  return &( disciple_drives[ which ].fdd );
+  return &( disciple_drives[ which ] );
 }
 
 static void
-disciple_event_index( libspectrum_dword last_tstates, int type GCC_UNUSED,
-		      void *user_data GCC_UNUSED )
-{
-  int next_tstates;
-  int i;
-
-  disciple_index_pulse = !disciple_index_pulse;
-  for( i = 0; i < DISCIPLE_NUM_DRIVES; i++ ) {
-    wd_fdc_drive *d = &disciple_drives[ i ];
-
-    d->index_pulse = disciple_index_pulse;
-    if( !disciple_index_pulse && d->index_interrupt ) {
-      wd_fdc_set_intrq( disciple_fdc );
-      d->index_interrupt = 0;
-    }
-  }
-  next_tstates = ( disciple_index_pulse ? 10 : 190 ) *
-    machine_current->timings.processor_speed / 1000;
-  event_add( last_tstates + next_tstates, index_event );
-}
-
-static void
 disciple_activate( void )
 {
   if( !memory_allocated ) {
Index: peripherals/disk/disk.h
===================================================================
--- peripherals/disk/disk.h	(revision 5113)
+++ peripherals/disk/disk.h	(working copy)
@@ -126,7 +126,7 @@
    d->weak   = d->fm     + DISK_CLEN( d->bpt )
 
 #define DISK_SET_TRACK( d, head, cyl ) \
-   DISK_SET_TRACK_IDX( d, d->sides * cyl + head )
+   DISK_SET_TRACK_IDX( (d), (d)->sides * cyl + head )
 
 const char *disk_strerror( int error );
 /* create an unformatted disk sides -> (1/2) cylinders -> track/side,
Index: peripherals/disk/fdd.c
===================================================================
--- peripherals/disk/fdd.c	(revision 5113)
+++ peripherals/disk/fdd.c	(working copy)
@@ -64,11 +64,13 @@
 fdd_event( libspectrum_dword last_tstates, int event, void *user_data );
 
 static int motor_event;
+static int index_event;
 
 void
 fdd_init_events( void )
 {
   motor_event = event_register( fdd_event, "FDD motor on" );
+  index_event = event_register( fdd_event, "FDD index" );
 
   upd_fdc_init_events();
   wd_fdc_init_events();
@@ -83,7 +85,7 @@
 }
 
 /*
- * disk->sides  1  2  1  2  1  2  1  2
+ * disk.sides  1  2  1  2  1  2  1  2
  * d->c_head    0  0  1  1  0  0  1  1
  * d->upside    0  0  0  0  1  1  1  1
  *
@@ -98,28 +100,28 @@
   if( !d->loaded )
     return;
 
-  if( d->unreadable || ( d->disk->sides == 1 && head == 1 ) ||
-      d->c_cylinder >= d->disk->cylinders ) {
-    d->disk->track = NULL;
-    d->disk->clocks = NULL;
-    d->disk->fm = NULL;
-    d->disk->weak = NULL;
+  if( d->unreadable || ( d->disk.sides == 1 && head == 1 ) ||
+      d->c_cylinder >= d->disk.cylinders ) {
+    d->disk.track = NULL;
+    d->disk.clocks = NULL;
+    d->disk.fm = NULL;
+    d->disk.weak = NULL;
     return;
   }
 
-  DISK_SET_TRACK( d->disk, head, d->c_cylinder );
-  d->c_bpt = d->disk->track[-3] + 256 * d->disk->track[-2];
+  DISK_SET_TRACK( &d->disk, head, d->c_cylinder );
+  d->c_bpt = d->disk.track[-3] + 256 * d->disk.track[-2];
   if( fact > 0 ) {
     /* this generate a bpt/fact +-10% triangular distribution skip in bytes 
        i know, we should use the higher bits of rand(), but we not
        keen on _real_ (pseudo)random numbers... ;)
     */
-    d->disk->i += d->c_bpt / fact + d->c_bpt *
+    d->disk.i += d->c_bpt / fact + d->c_bpt *
 		  ( rand() % 10 + rand() % 10 - 9 ) / fact / 100;
-    while( d->disk->i >= d->c_bpt )
-      d->disk->i -= d->c_bpt;
+    while( d->disk.i >= d->c_bpt )
+      d->disk.i -= d->c_bpt;
   }
-  d->index = d->disk->i ? 0 : 1;
+  d->index = d->disk.i ? 0 : 1;
 }
 
 /* initialise fdd */
@@ -127,9 +129,9 @@
 fdd_init( fdd_t *d, fdd_type_t type, const fdd_params_t *dt, int reinit )
 {
   int upsidedown = d->upsidedown;
+  int loaded = d->loaded;
   int selected = d->selected;
   int do_read_weak = d->do_read_weak;
-  disk_t *disk = d->disk;
   if( dt == NULL ) dt = &fdd_params[0];
 
   d->fdd_heads = d->fdd_cylinders = d->c_head = d->c_cylinder = 0;
@@ -152,12 +154,15 @@
   if( reinit ) {
     d->selected = selected;
     d->do_read_weak = do_read_weak;
+  } else {
+    fdd_unload( d );
   }
-  if( reinit && disk ) {
+  if( reinit && loaded ) {
     fdd_unload( d );
-    fdd_load( d, disk, upsidedown );
-  } else
-    d->disk = NULL;
+    fdd_load( d, upsidedown );
+  }
+   else
+    d->disk.data = NULL;
 
   return d->status = FDD_OK;
 }
@@ -188,6 +193,10 @@
     event_add_with_data( tstates + 4 *			/* 2 revolution: 2 * 200 / 1000 */
 			 machine_current->timings.processor_speed / 10,
 			 motor_event, d );
+    if( d->loaded ) /* index rotating */
+      event_add_with_data( tstates + ( d->index_pulse ? 10 : 190 ) *
+			 machine_current->timings.processor_speed / 1000,
+			 index_event, d );
   } else {
     event_add_with_data( tstates + 3 *			/* 1.5 revolution */
 			 machine_current->timings.processor_speed / 10,
@@ -224,32 +233,31 @@
 
 /* load a disk into fdd */
 int
-fdd_load( fdd_t *d, disk_t *disk, int upsidedown )
+fdd_load( fdd_t *d, int upsidedown )
 {
   if( d->type == FDD_TYPE_NONE )
     return d->status = FDD_NONE;
 
-  if( disk->sides < 0 || disk->sides > 2 ||
-      disk->cylinders < 0 || disk->cylinders > FDD_MAX_TRACK )
+  if( d->disk.sides < 0 || d->disk.sides > 2 ||
+      d->disk.cylinders < 0 || d->disk.cylinders > FDD_MAX_TRACK )
     return d->status = FDD_GEOM;
 
   if( d->auto_geom )
-    d->fdd_heads = disk->sides;		/* 1 or 2 */
+    d->fdd_heads = d->disk.sides;		/* 1 or 2 */
   if( d->auto_geom )
-    d->fdd_cylinders = disk->cylinders > settings_current.drive_40_max_track ?
+    d->fdd_cylinders = d->disk.cylinders > settings_current.drive_40_max_track ?
 				settings_current.drive_80_max_track : settings_current.drive_40_max_track;
 
-  if( disk->cylinders > d->fdd_cylinders + FDD_TRACK_TRESHOLD )
+  if( d->disk.cylinders > d->fdd_cylinders + FDD_TRACK_TRESHOLD )
     d->unreadable = 1;
 
-  d->disk = disk;
   d->upsidedown = upsidedown > 0 ? 1 : 0;
-  d->wrprot = d->disk->wrprot;		/* write protect */
+  d->wrprot = d->disk.wrprot;		/* write protect */
   d->loaded = 1;
   if( d->type == FDD_SHUGART && d->selected )
     fdd_head_load( d, 1 );
 
-  d->do_read_weak = disk->have_weak;
+  d->do_read_weak = d->disk.have_weak;
   fdd_set_data( d, FDD_LOAD_FACT );
   d->ready = ( d->motoron && d->loaded );
 
@@ -261,7 +269,6 @@
 {
   d->ready = d->loaded = 0;
   d->index = d->wrprot = 1;
-  d->disk = NULL;
   fdd_motoron( d, 0 );
   if( d->type == FDD_SHUGART && d->selected )
     fdd_head_load( d, 0 );
@@ -305,62 +312,62 @@
 int
 fdd_read_write_data( fdd_t *d, fdd_write_t write )
 {
-  if( !d->selected || !d->ready || !d->loadhead || d->disk->track == NULL ) {
+  if( !d->selected || !d->ready || !d->loadhead || d->disk.track == NULL ) {
     if( d->loaded && d->motoron ) {			/* spin the disk */
-      if( d->disk->i >= d->c_bpt ) {		/* next data byte */
-        d->disk->i = 0;
+      if( d->disk.i >= d->c_bpt ) {		/* next data byte */
+        d->disk.i = 0;
       }
       if( !write )
         d->data = 0x100;				/* no data */
-      d->disk->i++;
-      d->index = d->disk->i >= d->c_bpt ? 1 : 0;
+      d->disk.i++;
+      d->index = d->disk.i >= d->c_bpt ? 1 : 0;
     }
     return d->status = FDD_OK;
   }
 
-  if( d->disk->i >= d->c_bpt ) {		/* next data byte */
-    d->disk->i = 0;
+  if( d->disk.i >= d->c_bpt ) {		/* next data byte */
+    d->disk.i = 0;
   }
   if( write ) {
-    if( d->disk->wrprot ) {
-      d->disk->i++;
-      d->index = d->disk->i >= d->c_bpt ? 1 : 0;
+    if( d->disk.wrprot ) {
+      d->disk.i++;
+      d->index = d->disk.i >= d->c_bpt ? 1 : 0;
       return d->status = FDD_RDONLY;
     }
-    d->disk->track[ d->disk->i ] = d->data & 0x00ff;
+    d->disk.track[ d->disk.i ] = d->data & 0x00ff;
     if( d->data & 0xff00 )
-      bitmap_set( d->disk->clocks, d->disk->i );
+      bitmap_set( d->disk.clocks, d->disk.i );
     else
-      bitmap_reset( d->disk->clocks, d->disk->i );
+      bitmap_reset( d->disk.clocks, d->disk.i );
 
     if( d->marks & 0x01 )
-      bitmap_set( d->disk->fm, d->disk->i );
+      bitmap_set( d->disk.fm, d->disk.i );
     else
-      bitmap_reset( d->disk->fm, d->disk->i );
+      bitmap_reset( d->disk.fm, d->disk.i );
 #if 0		/* hmm... we cannot write weak data with 'standard' hardware */
     if( d->marks & 0x02 )
-      bitmap_set( d->disk->weak, d->disk->i );
+      bitmap_set( d->disk.weak, d->disk.i );
     else
-      bitmap_reset( d->disk->weak, d->disk->i );
+      bitmap_reset( d->disk.weak, d->disk.i );
 #else
-    bitmap_reset( d->disk->weak, d->disk->i );
+    bitmap_reset( d->disk.weak, d->disk.i );
 #endif
-    d->disk->dirty = 1;
+    d->disk.dirty = 1;
   } else {	/* read */
-    d->data = d->disk->track[ d->disk->i ];
-    if( bitmap_test( d->disk->clocks, d->disk->i ) )
+    d->data = d->disk.track[ d->disk.i ];
+    if( bitmap_test( d->disk.clocks, d->disk.i ) )
       d->data |= 0xff00;
     d->marks = 0;
-    if( bitmap_test( d->disk->fm, d->disk->i ) )
+    if( bitmap_test( d->disk.fm, d->disk.i ) )
       d->marks |= 0x01;
-    if( bitmap_test( d->disk->weak, d->disk->i ) ) {
+    if( bitmap_test( d->disk.weak, d->disk.i ) ) {
       d->marks |= 0x02;
       /* mess up data byte */
       d->data &= rand() % 0xff, d->data |= rand() % 0xff;
     }
   }
-  d->disk->i++;
-  d->index = d->disk->i >= d->c_bpt ? 1 : 0;
+  d->disk.i++;
+  d->index = d->disk.i >= d->c_bpt ? 1 : 0;
 
   return d->status = FDD_OK;
 }
@@ -380,7 +387,7 @@
   if( !d->loaded )
     return;
 
-  d->wrprot = d->disk->wrprot = wrprot;
+  d->wrprot = d->disk.wrprot = wrprot;
 }
 
 void
@@ -389,14 +396,32 @@
   if( !d->selected || !d->ready )
     return;
 
-  d->disk->i = 0;
+  d->disk.i = 0;
   d->index = 1;
 }
 
 static void
-fdd_event( libspectrum_dword last_tstates GCC_UNUSED, int event,
+fdd_event( libspectrum_dword last_tstates, int event,
            void *user_data ) 
 {
   fdd_t *d = user_data;
-  d->ready = ( d->motoron & d->loaded );	/* 0x01 & 0x01 */
+
+  if( event == motor_event ) {
+    d->ready = ( d->motoron & d->loaded );	/* 0x01 & 0x01 */
+    return;
+  }
+
+  d->index_pulse = !d->index_pulse;
+/*
+    if( !d->index_pulse && d->index_interrupt ) {
+      wd_fdc_set_intrq( ???_fdc );
+      d->index_interrupt = 0;
+    }
+*/
+//  d->fdc_index_pulse( d->index_pulse );
+
+  if( d->motoron & d->loaded ) /* keep rotating */
+    event_add_with_data( last_tstates + ( d->index_pulse ? 10 : 190 ) *
+			 machine_current->timings.processor_speed / 1000,
+			 index_event, d );
 }
Index: peripherals/disk/fdd.h
===================================================================
--- peripherals/disk/fdd.h	(revision 5113)
+++ peripherals/disk/fdd.h	(working copy)
@@ -88,7 +88,7 @@
   int data;		/* read/write to data byte 0x00nn or 0xffnn */
   int marks;		/* read/write other marks 0x01 -> FM 0x02 -> WEAK */
 
-  disk_t *disk;		/* pointer to inserted disk */
+  disk_t disk;		/* disk */
   int loaded;		/* disk loaded */
   int upsidedown;	/* flipped disk */
   int selected;		/* Drive Select line active */
@@ -104,7 +104,9 @@
   int c_bpt;		/* current track length in bytes */
   int motoron;		/* motor on */
   int loadhead;		/* head loaded */
+  int index_pulse;	/* 'second' index hole, to interrupts and others */
 
+  int index_interrupt;	/* wd_fdc may use it later ??? */
 } fdd_t;
 
 typedef struct fdd_params_t {
@@ -122,7 +124,7 @@
 /* initialize the fdd_t struct, and set fdd_heads and cylinders (e.g. 2/83 ) */
 int fdd_init( fdd_t *d, fdd_type_t type, const fdd_params_t *dt, int reinit );
 /* load the given disk into the fdd. if upsidedown = 1, floppy upsidedown in drive :) */
-int fdd_load( fdd_t *d, disk_t *disk, int upsidedown );
+int fdd_load( fdd_t *d, int upsidedown );
 /* unload the disk from fdd */
 void fdd_unload( fdd_t *d );
 /* set fdd head */
Index: peripherals/disk/opus.c
===================================================================
--- peripherals/disk/opus.c	(revision 5113)
+++ peripherals/disk/opus.c	(working copy)
@@ -64,12 +64,8 @@
 int opus_available = 0;
 int opus_active = 0;
 
-static int opus_index_pulse;
-
-static int index_event;
-
 static wd_fdc *opus_fdc;
-static wd_fdc_drive opus_drives[ OPUS_NUM_DRIVES ];
+static fdd_t opus_drives[ OPUS_NUM_DRIVES ];
 static ui_media_drive_info_t opus_ui_drives[ OPUS_NUM_DRIVES ];
 
 static libspectrum_byte opus_ram[ OPUS_RAM_SIZE ];
@@ -83,8 +79,6 @@
 static void opus_enabled_snapshot( libspectrum_snap *snap );
 static void opus_from_snapshot( libspectrum_snap *snap );
 static void opus_to_snapshot( libspectrum_snap *snap );
-static void opus_event_index( libspectrum_dword last_tstates, int type,
-			       void *user_data );
 
 static module_info_t opus_module_info = {
 
@@ -138,18 +132,18 @@
 opus_init( void )
 {
   int i;
-  wd_fdc_drive *d;
+  fdd_t *d;
 
   opus_fdc = wd_fdc_alloc_fdc( WD1770, 0, WD_FLAG_OPUS );
 
   for( i = 0; i < OPUS_NUM_DRIVES; i++ ) {
     d = &opus_drives[ i ];
-    fdd_init( &d->fdd, FDD_SHUGART, NULL, 0 );	/* drive geometry 'autodetect' */
+    fdd_init( d, FDD_SHUGART, NULL, 0 );	/* drive geometry 'autodetect' */
     d->disk.flag = DISK_FLAG_NONE;
   }
 
   opus_fdc->current_drive = &opus_drives[ 0 ];
-  fdd_select( &opus_drives[ 0 ].fdd, 1 );
+  fdd_select( &opus_drives[ 0 ], 1 );
   opus_fdc->dden = 1;
   opus_fdc->set_intrq = NULL;
   opus_fdc->reset_intrq = NULL;
@@ -157,8 +151,6 @@
   opus_fdc->reset_datarq = NULL;
   opus_fdc->iface = NULL;
 
-  index_event = event_register( opus_event_index, "Opus index" );
-
   module_register( &opus_module_info );
 
   opus_rom_memory_source = memory_source_register( "Opus ROM" );
@@ -170,9 +162,7 @@
 
   periph_register( PERIPH_TYPE_OPUS, &opus_periph );
   for( i = 0; i < OPUS_NUM_DRIVES; i++ ) {
-    d = &opus_drives[ i ];
-    opus_ui_drives[ i ].fdd = &d->fdd;
-    opus_ui_drives[ i ].disk = &d->disk;
+    opus_ui_drives[ i ].fdd = &opus_drives[ i ];
     ui_media_drive_register( &opus_ui_drives[ i ] );
   }
 }
@@ -181,13 +171,10 @@
 opus_reset( int hard_reset )
 {
   int i;
-  wd_fdc_drive *d;
 
   opus_active = 0;
   opus_available = 0;
 
-  event_remove_type( index_event );
-
   if( !periph_is_active( PERIPH_TYPE_OPUS ) ) {
     return;
   }
@@ -220,7 +207,6 @@
   control_b  = 0;
 
   opus_available = 1;
-  opus_index_pulse = 0;
 
   if( hard_reset )
     memset( opus_ram, 0, TRUE_OPUS_RAM_SIZE );
@@ -228,19 +214,13 @@
   wd_fdc_master_reset( opus_fdc );
 
   for( i = 0; i < OPUS_NUM_DRIVES; i++ ) {
-    d = &opus_drives[ i ];
-
-    d->index_pulse = 0;
-    d->index_interrupt = 0;
-
     ui_media_drive_update_menus( &opus_ui_drives[ i ],
                                  UI_MEDIA_DRIVE_UPDATE_ALL );
   }
 
   opus_fdc->current_drive = &opus_drives[ 0 ];
-  fdd_select( &opus_drives[ 0 ].fdd, 1 );
+  fdd_select( &opus_drives[ 0 ], 1 );
   machine_current->memory_map();
-  opus_event_index( 0, index_event, NULL );
 
   ui_statusbar_update( UI_STATUSBAR_ITEM_DISK, UI_STATUSBAR_STATE_INACTIVE );
 }
@@ -283,16 +263,16 @@
         side = ( data & 0x10 )>>4 ? 1 : 0;
 
         for( i = 0; i < OPUS_NUM_DRIVES; i++ ) {
-          fdd_set_head( &opus_drives[ i ].fdd, side );
+          fdd_set_head( &opus_drives[ i ], side );
         }
 
-        fdd_select( &opus_drives[ (!drive) ].fdd, 0 );
-        fdd_select( &opus_drives[ drive ].fdd, 1 );
+        fdd_select( &opus_drives[ (!drive) ], 0 );
+        fdd_select( &opus_drives[ drive ], 1 );
 
         if( opus_fdc->current_drive != &opus_drives[ drive ] ) {
-          if( opus_fdc->current_drive->fdd.motoron ) {        /* swap motoron */
-            fdd_motoron( &opus_drives[ (!drive) ].fdd, 0 );
-            fdd_motoron( &opus_drives[ drive ].fdd, 1 );
+          if( opus_fdc->current_drive->motoron ) {        /* swap motoron */
+            fdd_motoron( &opus_drives[ (!drive) ], 0 );
+            fdd_motoron( &opus_drives[ drive ], 1 );
           }
           opus_fdc->current_drive = &opus_drives[ drive ];
         }
@@ -367,31 +347,9 @@
 fdd_t *
 opus_get_fdd( opus_drive_number which )
 {
-  return &( opus_drives[ which ].fdd );
+  return &( opus_drives[ which ] );
 }
 
-static void
-opus_event_index( libspectrum_dword last_tstates, int type GCC_UNUSED,
-                   void *user_data GCC_UNUSED )
-{
-  int next_tstates;
-  int i;
-
-  opus_index_pulse = !opus_index_pulse;
-  for( i = 0; i < OPUS_NUM_DRIVES; i++ ) {
-    wd_fdc_drive *d = &opus_drives[ i ];
-
-    d->index_pulse = opus_index_pulse;
-    if( !opus_index_pulse && d->index_interrupt ) {
-      wd_fdc_set_intrq( opus_fdc );
-      d->index_interrupt = 0;
-    }
-  }
-  next_tstates = ( opus_index_pulse ? 10 : 190 ) *
-    machine_current->timings.processor_speed / 1000;
-  event_add( last_tstates + next_tstates, index_event );
-}
-
 libspectrum_byte
 opus_read( libspectrum_word address )
 {
Index: peripherals/disk/plusd.c
===================================================================
--- peripherals/disk/plusd.c	(revision 5113)
+++ peripherals/disk/plusd.c	(working copy)
@@ -53,12 +53,8 @@
 int plusd_available = 0;
 int plusd_active = 0;
 
-static int plusd_index_pulse;
-
-static int index_event;
-
 static wd_fdc *plusd_fdc;
-static wd_fdc_drive plusd_drives[ PLUSD_NUM_DRIVES ];
+static fdd_t plusd_drives[ PLUSD_NUM_DRIVES ];
 static ui_media_drive_info_t plusd_ui_drives[ PLUSD_NUM_DRIVES ];
 
 static libspectrum_byte *plusd_ram;
@@ -69,8 +65,6 @@
 static void plusd_enabled_snapshot( libspectrum_snap *snap );
 static void plusd_from_snapshot( libspectrum_snap *snap );
 static void plusd_to_snapshot( libspectrum_snap *snap );
-static void plusd_event_index( libspectrum_dword last_tstates, int type,
-			       void *user_data );
 static void plusd_activate( void );
 
 static module_info_t plusd_module_info = {
@@ -141,18 +135,18 @@
 plusd_init( void )
 {
   int i;
-  wd_fdc_drive *d;
+  fdd_t *d;
 
   plusd_fdc = wd_fdc_alloc_fdc( WD1770, 0, WD_FLAG_NONE );
 
   for( i = 0; i < PLUSD_NUM_DRIVES; i++ ) {
     d = &plusd_drives[ i ];
-    fdd_init( &d->fdd, FDD_SHUGART, NULL, 0 );
+    fdd_init( d, FDD_SHUGART, NULL, 0 );
     d->disk.flag = DISK_FLAG_NONE;
   }
 
   plusd_fdc->current_drive = &plusd_drives[ 0 ];
-  fdd_select( &plusd_drives[ 0 ].fdd, 1 );
+  fdd_select( &plusd_drives[ 0 ], 1 );
   plusd_fdc->dden = 1;
   plusd_fdc->set_intrq = NULL;
   plusd_fdc->reset_intrq = NULL;
@@ -160,8 +154,6 @@
   plusd_fdc->reset_datarq = NULL;
   plusd_fdc->iface = NULL;
 
-  index_event = event_register( plusd_event_index, "+D index" );
-
   module_register( &plusd_module_info );
 
   plusd_memory_source = memory_source_register( "PlusD" );
@@ -173,9 +165,7 @@
   periph_register( PERIPH_TYPE_PLUSD, &plusd_periph );
 
   for( i = 0; i < PLUSD_NUM_DRIVES; i++ ) {
-    d = &plusd_drives[ i ];
-    plusd_ui_drives[ i ].fdd = &d->fdd;
-    plusd_ui_drives[ i ].disk = &d->disk;
+    plusd_ui_drives[ i ].fdd = &plusd_drives[ i ];
     ui_media_drive_register( &plusd_ui_drives[ i ] );
   }
 }
@@ -184,13 +174,10 @@
 plusd_reset( int hard_reset )
 {
   int i;
-  wd_fdc_drive *d;
 
   plusd_active = 0;
   plusd_available = 0;
 
-  event_remove_type( index_event );
-
   if( !periph_is_active( PERIPH_TYPE_PLUSD ) ) {
     return;
   }
@@ -212,7 +199,6 @@
 
   plusd_available = 1;
   plusd_active = 1;
-  plusd_index_pulse = 0;
 
   if( hard_reset )
     memset( plusd_ram, 0, 0x2000 );
@@ -220,19 +206,13 @@
   wd_fdc_master_reset( plusd_fdc );
 
   for( i = 0; i < PLUSD_NUM_DRIVES; i++ ) {
-    d = &plusd_drives[ i ];
-
-    d->index_pulse = 0;
-    d->index_interrupt = 0;
-
     ui_media_drive_update_menus( &plusd_ui_drives[ i ],
                                  UI_MEDIA_DRIVE_UPDATE_ALL );
   }
 
   plusd_fdc->current_drive = &plusd_drives[ 0 ];
-  fdd_select( &plusd_drives[ 0 ].fdd, 1 );
+  fdd_select( &plusd_drives[ 0 ], 1 );
   machine_current->memory_map();
-  plusd_event_index( 0, index_event, NULL );
 
   ui_statusbar_update( UI_STATUSBAR_ITEM_DISK, UI_STATUSBAR_STATE_INACTIVE );
 }
@@ -309,15 +289,15 @@
 
   /* TODO: set current_drive to NULL when bits 0 and 1 of b are '00' or '11' */
   for( i = 0; i < PLUSD_NUM_DRIVES; i++ ) {
-    fdd_set_head( &plusd_drives[ i ].fdd, side );
+    fdd_set_head( &plusd_drives[ i ], side );
   }
-  fdd_select( &plusd_drives[ (!drive) ].fdd, 0 );
-  fdd_select( &plusd_drives[ drive ].fdd, 1 );
+  fdd_select( &plusd_drives[ (!drive) ], 0 );
+  fdd_select( &plusd_drives[ drive ], 1 );
 
   if( plusd_fdc->current_drive != &plusd_drives[ drive ] ) {
-    if( plusd_fdc->current_drive->fdd.motoron ) {            /* swap motoron */
-      fdd_motoron( &plusd_drives[ (!drive) ].fdd, 0 );
-      fdd_motoron( &plusd_drives[ drive ].fdd, 1 );
+    if( plusd_fdc->current_drive->motoron ) {            /* swap motoron */
+      fdd_motoron( &plusd_drives[ (!drive) ], 0 );
+      fdd_motoron( &plusd_drives[ drive ], 1 );
     }
     plusd_fdc->current_drive = &plusd_drives[ drive ];
   }
@@ -375,31 +355,9 @@
 fdd_t *
 plusd_get_fdd( plusd_drive_number which )
 {
-  return &( plusd_drives[ which ].fdd );
+  return &( plusd_drives[ which ] );
 }
 
-static void
-plusd_event_index( libspectrum_dword last_tstates, int type GCC_UNUSED,
-                   void *user_data GCC_UNUSED )
-{
-  int next_tstates;
-  int i;
-
-  plusd_index_pulse = !plusd_index_pulse;
-  for( i = 0; i < PLUSD_NUM_DRIVES; i++ ) {
-    wd_fdc_drive *d = &plusd_drives[ i ];
-
-    d->index_pulse = plusd_index_pulse;
-    if( !plusd_index_pulse && d->index_interrupt ) {
-      wd_fdc_set_intrq( plusd_fdc );
-      d->index_interrupt = 0;
-    }
-  }
-  next_tstates = ( plusd_index_pulse ? 10 : 190 ) *
-    machine_current->timings.processor_speed / 1000;
-  event_add( last_tstates + next_tstates, index_event );
-}
-
 static libspectrum_byte *
 alloc_and_copy_page( libspectrum_byte* source_page )
 {
Index: peripherals/disk/upd_fdc.c
===================================================================
--- peripherals/disk/upd_fdc.c	(revision 5113)
+++ peripherals/disk/upd_fdc.c	(working copy)
@@ -131,7 +131,7 @@
   int i;
   for( i = 0; i < 4; i++ )
     if( f->drive[i] != NULL )
-      fdd_select( &f->drive[i]->fdd, i == 0 ? 1 : 0 );
+      fdd_select( f->drive[i], i == 0 ? 1 : 0 );
   f->current_drive = f->drive[0];
 
   f->main_status = UPD_FDC_MAIN_DATAREQ;
@@ -159,9 +159,9 @@
 }
 
 static void
-crc_add( upd_fdc *f, upd_fdc_drive *d )
+crc_add( upd_fdc *f, fdd_t *d )
 {
-  f->crc = crc_fdc( f->crc, d->fdd.data & 0xff );
+  f->crc = crc_fdc( f->crc, d->data & 0xff );
 }
 
 /* 
@@ -174,7 +174,7 @@
 read_id( upd_fdc *f )
 {
   int i;
-  upd_fdc_drive *d = f->current_drive;
+  fdd_t *d = f->current_drive;
 
   f->status_register[1] &= ~( UPD_FDC_ST1_CRC_ERROR | 
     			      UPD_FDC_ST1_MISSING_AM |
@@ -181,51 +181,51 @@
     			      UPD_FDC_ST1_NO_DATA );
   f->id_mark = UPD_FDC_AM_NONE;
   i = f->rev;
-  while( i == f->rev && d->fdd.ready ) {
-    fdd_read_write_data( &d->fdd, FDD_READ ); if( d->fdd.index ) f->rev--;
+  while( i == f->rev && d->ready ) {
+    fdd_read_write_data( d, FDD_READ ); if( d->index ) f->rev--;
     crc_preset( f );
     if( f->mf ) {	/* double density (MFM) */
-      if( d->fdd.data == 0xffa1 ) {
+      if( d->data == 0xffa1 ) {
         crc_add( f, d );
-	fdd_read_write_data( &d->fdd, FDD_READ ); crc_add( f, d );
-	if( d->fdd.index ) f->rev--;
-	if( d->fdd.data != 0xffa1 )
+	fdd_read_write_data( d, FDD_READ ); crc_add( f, d );
+	if( d->index ) f->rev--;
+	if( d->data != 0xffa1 )
 	  continue;
-	fdd_read_write_data( &d->fdd, FDD_READ ); crc_add( f, d );
-	if( d->fdd.index ) f->rev--;
-	if( d->fdd.data != 0xffa1 )
+	fdd_read_write_data( d, FDD_READ ); crc_add( f, d );
+	if( d->index ) f->rev--;
+	if( d->data != 0xffa1 )
 	  continue;
       } else {		/* no 0xa1 with missing clock... */
 	continue;
       }
     }
-    fdd_read_write_data( &d->fdd, FDD_READ );
-    if( d->fdd.index ) f->rev--;
+    fdd_read_write_data( d, FDD_READ );
+    if( d->index ) f->rev--;
     if( f->mf ) {	/* double density (MFM) */
-      if( d->fdd.data != 0x00fe )
+      if( d->data != 0x00fe )
 	continue;
     } else {		/* single density (FM) */
-      if( d->fdd.data != 0xfffe )
+      if( d->data != 0xfffe )
 	continue;
     }
     crc_add( f, d );
-    fdd_read_write_data( &d->fdd, FDD_READ ); crc_add( f, d );
-    if( d->fdd.index ) f->rev--;
-    f->id_track = d->fdd.data;
-    fdd_read_write_data( &d->fdd, FDD_READ ); crc_add( f, d );
-    if( d->fdd.index ) f->rev--;
-    f->id_head = d->fdd.data;
-    fdd_read_write_data( &d->fdd, FDD_READ ); crc_add( f, d );
-    if( d->fdd.index ) f->rev--;
-    f->id_sector = d->fdd.data;
-    fdd_read_write_data( &d->fdd, FDD_READ ); crc_add( f, d );
-    if( d->fdd.index ) f->rev--;
-    f->id_length = d->fdd.data > MAX_SIZE_CODE ? MAX_SIZE_CODE : d->fdd.data;
+    fdd_read_write_data( d, FDD_READ ); crc_add( f, d );
+    if( d->index ) f->rev--;
+    f->id_track = d->data;
+    fdd_read_write_data( d, FDD_READ ); crc_add( f, d );
+    if( d->index ) f->rev--;
+    f->id_head = d->data;
+    fdd_read_write_data( d, FDD_READ ); crc_add( f, d );
+    if( d->index ) f->rev--;
+    f->id_sector = d->data;
+    fdd_read_write_data( d, FDD_READ ); crc_add( f, d );
+    if( d->index ) f->rev--;
+    f->id_length = d->data > MAX_SIZE_CODE ? MAX_SIZE_CODE : d->data;
     f->sector_length = 0x80 << f->id_length; 
-    fdd_read_write_data( &d->fdd, FDD_READ ); crc_add( f, d );
-    if( d->fdd.index ) f->rev--;
-    fdd_read_write_data( &d->fdd, FDD_READ ); crc_add( f, d );
-    if( d->fdd.index ) f->rev--;
+    fdd_read_write_data( d, FDD_READ ); crc_add( f, d );
+    if( d->index ) f->rev--;
+    fdd_read_write_data( d, FDD_READ ); crc_add( f, d );
+    if( d->index ) f->rev--;
 
     if( f->crc != 0x0000 ) {
       f->status_register[1] |= UPD_FDC_ST1_CRC_ERROR | UPD_FDC_ST1_NO_DATA;
@@ -236,7 +236,7 @@
       return 0;		/* found and OK */
     }
   }
-  if(!d->fdd.ready) f->rev = 0;
+  if(!d->ready) f->rev = 0;
   f->status_register[1] |= UPD_FDC_ST1_MISSING_AM | UPD_FDC_ST1_NO_DATA;	/*FIXME _NO_DATA? */
   return 2;		/* not found */
 }
@@ -250,16 +250,16 @@
 static int
 read_datamark( upd_fdc *f )
 {
-  upd_fdc_drive *d = f->current_drive;
+  fdd_t *d = f->current_drive;
   int i;
 
   if( f->mf ) {	/* double density (MFM) */
     for( i = 40; i > 0; i-- ) {
-      fdd_read_write_data( &d->fdd, FDD_READ );
-      if( d->fdd.data == 0x4e )		/* read next */
+      fdd_read_write_data( d, FDD_READ );
+      if( d->data == 0x4e )		/* read next */
 	continue;
 
-      if( d->fdd.data == 0x00 )		/* go to PLL sync */
+      if( d->data == 0x00 )		/* go to PLL sync */
 	break;
 
       f->status_register[2] |= UPD_FDC_ST2_MISSING_DM;
@@ -267,29 +267,29 @@
     } 
     for( ; i > 0; i-- ) {
       crc_preset( f );
-      fdd_read_write_data( &d->fdd, FDD_READ ); crc_add( f, d );
-      if( d->fdd.data == 0x00 )
+      fdd_read_write_data( d, FDD_READ ); crc_add( f, d );
+      if( d->data == 0x00 )
 	continue;
 
-      if( d->fdd.data == 0xffa1 )	/* got to a1 mark */
+      if( d->data == 0xffa1 )	/* got to a1 mark */
 	break;
 
       f->status_register[2] |= UPD_FDC_ST2_MISSING_DM;
       return 1;
     }
-    for( i = d->fdd.data == 0xffa1 ? 2 : 3; i > 0; i-- ) {
-      fdd_read_write_data( &d->fdd, FDD_READ ); crc_add( f, d );
-      if( d->fdd.data != 0xffa1 ) {
+    for( i = d->data == 0xffa1 ? 2 : 3; i > 0; i-- ) {
+      fdd_read_write_data( d, FDD_READ ); crc_add( f, d );
+      if( d->data != 0xffa1 ) {
         f->status_register[2] |= UPD_FDC_ST2_MISSING_DM;
 	return 1;
       }
     } 
-    fdd_read_write_data( &d->fdd, FDD_READ ); crc_add( f, d );
-    if( d->fdd.data < 0x00f8 || d->fdd.data > 0x00fb ) { /* !fb deleted mark */
+    fdd_read_write_data( d, FDD_READ ); crc_add( f, d );
+    if( d->data < 0x00f8 || d->data > 0x00fb ) { /* !fb deleted mark */
       f->status_register[2] |= UPD_FDC_ST2_MISSING_DM;
       return 1;
     }
-    if( d->fdd.data != 0x00fb )
+    if( d->data != 0x00fb )
       f->ddam = 1;
     else
       f->ddam = 0;
@@ -296,11 +296,11 @@
     return 0;
   } else {		/* SD -> FM */
     for( i = 30; i > 0; i-- ) {
-      fdd_read_write_data( &d->fdd, FDD_READ );
-      if( d->fdd.data == 0xff )		/* read next */
+      fdd_read_write_data( d, FDD_READ );
+      if( d->data == 0xff )		/* read next */
 	continue;
 
-      if( d->fdd.data == 0x00 )		/* go to PLL sync */
+      if( d->data == 0x00 )		/* go to PLL sync */
 	break;
 
       f->status_register[2] |= UPD_FDC_ST2_MISSING_DM;
@@ -308,11 +308,11 @@
     } 
     for( ; i > 0; i-- ) {
       crc_preset( f );
-      fdd_read_write_data( &d->fdd, FDD_READ ); crc_add( f, d );
-      if( d->fdd.data == 0x00 )
+      fdd_read_write_data( d, FDD_READ ); crc_add( f, d );
+      if( d->data == 0x00 )
 	continue;
 
-      if( d->fdd.data >= 0xfff8 && d->fdd.data <= 0xfffb )	/* !fb deleted mark */
+      if( d->data >= 0xfff8 && d->data <= 0xfffb )	/* !fb deleted mark */
 	break;
 
       f->status_register[2] |= UPD_FDC_ST2_MISSING_DM;
@@ -319,13 +319,13 @@
       return 1;
     }
     if( i == 0 ) {
-      fdd_read_write_data( &d->fdd, FDD_READ ); crc_add( f, d );
-      if( d->fdd.data < 0xfff8 || d->fdd.data > 0xfffb ) {	/* !fb deleted mark */
+      fdd_read_write_data( d, FDD_READ ); crc_add( f, d );
+      if( d->data < 0xfff8 || d->data > 0xfffb ) {	/* !fb deleted mark */
         f->status_register[2] |= UPD_FDC_ST2_MISSING_DM;
 	return 1;
       }
     }
-    if( d->fdd.data != 0x00fb )
+    if( d->data != 0x00fb )
       f->ddam = 1;
     else
       f->ddam = 0;
@@ -421,7 +421,7 @@
 seek_step( upd_fdc *f, int start )
 {
   int i, j;
-  upd_fdc_drive *d;
+  fdd_t *d;
 
   if( start ) {
     i = f->us;
@@ -449,7 +449,7 @@
 
   /* There is need to seek? */
   if( f->pcn[i] == f->ncn[i] &&
-      f->seek[i] == 2 && !d->fdd.tr00 ) {	/* recalibrate fail */
+      f->seek[i] == 2 && !d->tr00 ) {	/* recalibrate fail */
     f->seek[i] = 5;				/* abnormal termination */
     f->seek_age[i] = 0;
     f->intrq = UPD_INTRQ_SEEK;
@@ -460,7 +460,7 @@
 
   /* There is need to seek? */
   if( f->pcn[i] == f->ncn[i] || 
-    ( f->seek[i] == 2 && d->fdd.tr00 ) ) {	/* correct position */
+    ( f->seek[i] == 2 && d->tr00 ) ) {	/* correct position */
     if( f->seek[i] == 2 )			/* recalibrate */
       f->pcn[i] = 0; 
     f->seek[i] = 4;				/* normal termination */
@@ -471,7 +471,7 @@
   }
 
   /* Drive not ready */
-  if( !d->fdd.ready ) {
+  if( !d->ready ) {
     if( f->seek[i] == 2 )			/* recalibrate */
       f->pcn[i] = f->rec[i] - ( 77 - f->pcn[i] ); 	/* restore PCN */
     f->seek[i] = 6;				/* drive not ready termination */
@@ -483,7 +483,7 @@
 
   /* Send step */
   if( f->pcn[i] != f->ncn[i] ) {	/**FIXME if d->tr00 == 1 ??? */
-    fdd_step( &d->fdd, f->pcn[i] > f->ncn[i] ? 
+    fdd_step( d, f->pcn[i] > f->ncn[i] ? 
                         FDD_STEP_OUT : FDD_STEP_IN );
     f->pcn[i] += f->pcn[i] > f->ncn[i] ? -1 : 1;
 
@@ -697,7 +697,7 @@
 start_write_data( upd_fdc *f )
 {
   int i;
-  upd_fdc_drive *d = f->current_drive;
+  fdd_t *d = f->current_drive;
 
 multi_track_next:
   if( f->first_rw || f->read_id ||
@@ -734,24 +734,24 @@
     }
 
     for( i = 11; i > 0; i-- )	/* "delay" 11 GAP byte */
-      fdd_read_write_data( &d->fdd, FDD_READ );
+      fdd_read_write_data( d, FDD_READ );
     if( f->mf )					/* MFM */
       for( i = 11; i > 0; i-- )	/* "delay" another 11 GAP byte */
-	fdd_read_write_data( &d->fdd, FDD_READ );
+	fdd_read_write_data( d, FDD_READ );
 
-    d->fdd.data = 0x00;
+    d->data = 0x00;
     for( i = f->mf ? 12 : 6; i > 0; i-- )	/* write 6/12 zero */
-      fdd_read_write_data( &d->fdd, FDD_WRITE );
+      fdd_read_write_data( d, FDD_WRITE );
     crc_preset( f );
     if( f->mf ) {				/* MFM */
-      d->fdd.data = 0xffa1;
+      d->data = 0xffa1;
       for( i = 3; i > 0; i-- ) {		/* write 3 0xa1 with clock mark */
-	fdd_read_write_data( &d->fdd, FDD_WRITE ); crc_add( f, d );
+	fdd_read_write_data( d, FDD_WRITE ); crc_add( f, d );
       }
     }
-    d->fdd.data = ( f->del_data ? 0x00f8 : 0x00fb ) |
+    d->data = ( f->del_data ? 0x00f8 : 0x00fb ) |
     			( f->mf ? 0x0000 : 0xff00 );	/* write data mark */
-    fdd_read_write_data( &d->fdd, FDD_WRITE ); crc_add( f, d );
+    fdd_read_write_data( d, FDD_WRITE ); crc_add( f, d );
   } else {
     f->data_register[1]++;		/* next track */
     f->data_register[3] = 1;		/* first sector */
@@ -787,33 +787,33 @@
 start_write_id( upd_fdc *f )
 {
   int i;
-  upd_fdc_drive *d = f->current_drive;
+  fdd_t *d = f->current_drive;
 
-  d->fdd.data = f->mf ? 0x4e : 0xff;
+  d->data = f->mf ? 0x4e : 0xff;
   for( i = 40; i > 0; i-- )	/* write 40 GAP byte */
-    fdd_read_write_data( &d->fdd, FDD_WRITE );
+    fdd_read_write_data( d, FDD_WRITE );
   if( f->mf )					/* MFM */
     for( i = 40; i > 0; i-- )	/* write another 40 GAP byte */
-      fdd_read_write_data( &d->fdd, FDD_WRITE );
-  d->fdd.data = 0x00;
+      fdd_read_write_data( d, FDD_WRITE );
+  d->data = 0x00;
   for( i = f->mf ? 12 : 6; i > 0; i-- )	/* write 6/12 zero */
-    fdd_read_write_data( &d->fdd, FDD_WRITE );
+    fdd_read_write_data( d, FDD_WRITE );
   crc_preset( f );
   if( f->mf ) {				/* MFM */
-    d->fdd.data = 0xffc2;
+    d->data = 0xffc2;
     for( i = 3; i > 0; i-- ) {		/* write 3 0xc2 with clock mark */
-      fdd_read_write_data( &d->fdd, FDD_WRITE );
+      fdd_read_write_data( d, FDD_WRITE );
     }
   }
-  d->fdd.data = 0x00fc | ( f->mf ? 0x0000 : 0xff00 );	/* write index mark */
-  fdd_read_write_data( &d->fdd, FDD_WRITE );
+  d->data = 0x00fc | ( f->mf ? 0x0000 : 0xff00 );	/* write index mark */
+  fdd_read_write_data( d, FDD_WRITE );
 
-  d->fdd.data = f->mf ? 0x4e : 0xff;	/* postindex GAP */
+  d->data = f->mf ? 0x4e : 0xff;	/* postindex GAP */
   for( i = 26; i > 0; i-- )	/* write 26 GAP byte */
-    fdd_read_write_data( &d->fdd, FDD_WRITE );
+    fdd_read_write_data( d, FDD_WRITE );
   if( f->mf )					/* MFM */
     for( i = 24; i > 0; i-- )	/* write another 24 GAP byte */
-      fdd_read_write_data( &d->fdd, FDD_WRITE );
+      fdd_read_write_data( d, FDD_WRITE );
 
   f->main_status |= UPD_FDC_MAIN_DATAREQ | UPD_FDC_MAIN_DATA_WRITE;
   f->data_offset = 0;
@@ -832,16 +832,16 @@
     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->fdd );		/* start reading from index hole */
+      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->fdd );		/* start writing from index hole */
+      fdd_wait_index_hole( f->current_drive );		/* start writing from index hole */
       start_write_id( f );
     }
   } else {
-    fdd_head_load( &f->current_drive->fdd, 1 );
+    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,
@@ -863,7 +863,7 @@
   }
 
   if( event == head_event ) {
-    fdd_head_load( &f->current_drive->fdd, 0 );
+    fdd_head_load( f->current_drive, 0 );
     f->head_load = 0;
     return;
   }
@@ -885,12 +885,12 @@
   } 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->fdd );		/* start reading from index hole */
+    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->fdd );		/* start writing from index hole */
+    fdd_wait_index_hole( f->current_drive );		/* start writing from index hole */
     start_write_id( f );
   }
 
@@ -908,7 +908,7 @@
 {
   libspectrum_byte r;
 
-  upd_fdc_drive *d = f->current_drive;
+  fdd_t *d = f->current_drive;
 
   if( !( f->main_status & UPD_FDC_MAIN_DATAREQ ) || 
       !( f->main_status & UPD_FDC_MAIN_DATA_READ ) )
@@ -916,31 +916,31 @@
 
   if( f->state == UPD_FDC_STATE_EXE ) {		/* READ_DATA/READ_DIAG */
     f->data_offset++;				/* count read bytes */
-    fdd_read_write_data( &d->fdd, FDD_READ ); crc_add( f, d ); /* read a byte */
+    fdd_read_write_data( d, FDD_READ ); crc_add( f, d ); /* read a byte */
 
     /* Speedlock hack */
-    if( f->speedlock > 0 && !d->fdd.do_read_weak ) {	/* do not conflict with fdd weak reads */
-      if( f->data_offset < 64 && d->fdd.data != 0xe5 )
+    if( f->speedlock > 0 && !d->do_read_weak ) {	/* do not conflict with fdd weak reads */
+      if( f->data_offset < 64 && d->data != 0xe5 )
         f->speedlock = 2;		/* W.E.C Le Mans type ... */
       else if( ( f->speedlock > 1 || f->data_offset < 64 ) &&
 	       !( f->data_offset % 29 ) ) {
-	d->fdd.data ^= f->data_offset;	/* mess up data */
+	d->data ^= f->data_offset;	/* mess up data */
 	crc_add( f, d );			/* mess up crc */
       }
     }
     /* EOSpeedlock hack */
 
-    r = d->fdd.data & 0xff;
+    r = d->data & 0xff;
     if( f->data_offset == f->rlen ) {	/* send only rlen byte to host */
       while( f->data_offset < f->sector_length ) {
-	fdd_read_write_data( &d->fdd, FDD_READ ); crc_add( f, d );
+	fdd_read_write_data( d, FDD_READ ); crc_add( f, d );
 	f->data_offset++;
       }
     }
     if( ( f->cmd->id == UPD_CMD_READ_DIAG || f->cmd->id == UPD_CMD_READ_DATA )
         && f->data_offset == f->sector_length ) {       /* read the CRC */
-      fdd_read_write_data( &d->fdd, FDD_READ ); crc_add( f, d );
-      fdd_read_write_data( &d->fdd, FDD_READ ); crc_add( f, d );
+      fdd_read_write_data( d, FDD_READ ); crc_add( f, d );
+      fdd_read_write_data( d, FDD_READ ); crc_add( f, d );
       if( f->crc != 0x000 ) {
 	f->status_register[2] |= UPD_FDC_ST2_DATA_ERROR;
 	f->status_register[1] |= UPD_FDC_ST1_CRC_ERROR;
@@ -1004,9 +1004,8 @@
 {
   int i, terminated = 0;
   unsigned int u;
-  upd_fdc_drive *d;
+  fdd_t *d;
 
-  
   if( !( f->main_status & UPD_FDC_MAIN_DATAREQ ) || 
       ( f->main_status & UPD_FDC_MAIN_DATA_READ ) )
     return;
@@ -1021,58 +1020,58 @@
       if( f->data_offset == 4 ) {			/* C, H, R, N done => format track */
 	event_remove_type( timeout_event );
 
-        d->fdd.data = 0x00;
+        d->data = 0x00;
         for( i = f->mf ? 12 : 6; i > 0; i-- )	/* write 6/12 zero */
-          fdd_read_write_data( &d->fdd, FDD_WRITE );
+          fdd_read_write_data( d, FDD_WRITE );
         crc_preset( f );
         if( f->mf ) {				/* MFM */
-          d->fdd.data = 0xffa1;
+          d->data = 0xffa1;
           for( i = 3; i > 0; i-- ) {		/* write 3 0xa1 with clock mark */
-	    fdd_read_write_data( &d->fdd, FDD_WRITE ); crc_add( f, d );
+	    fdd_read_write_data( d, FDD_WRITE ); crc_add( f, d );
           }
         }
-        d->fdd.data = 0x00fe | ( f->mf ? 0x0000 : 0xff00 );	/* write id mark */
-        fdd_read_write_data( &d->fdd, FDD_WRITE ); crc_add( f, d );
+        d->data = 0x00fe | ( f->mf ? 0x0000 : 0xff00 );	/* write id mark */
+        fdd_read_write_data( d, FDD_WRITE ); crc_add( f, d );
 	for( i = 0; i < 4; i++ ) {
-    	  d->fdd.data =  f->data_register[i + 5];	/* write id fields */
-          fdd_read_write_data( &d->fdd, FDD_WRITE ); crc_add( f, d );
+    	  d->data =  f->data_register[i + 5];	/* write id fields */
+          fdd_read_write_data( d, FDD_WRITE ); crc_add( f, d );
 	}
-        d->fdd.data = f->crc >> 8;
-        fdd_read_write_data( &d->fdd, FDD_WRITE );	/* write crc1 */
-        d->fdd.data = f->crc & 0xff;
-        fdd_read_write_data( &d->fdd, FDD_WRITE );	/* write crc2 */
+        d->data = f->crc >> 8;
+        fdd_read_write_data( d, FDD_WRITE );	/* write crc1 */
+        d->data = f->crc & 0xff;
+        fdd_read_write_data( d, FDD_WRITE );	/* write crc2 */
 
-        d->fdd.data = f->mf ? 0x4e : 0xff;
+        d->data = f->mf ? 0x4e : 0xff;
         for( i = 11; i > 0; i-- )	/* write 11 GAP byte */
-          fdd_read_write_data( &d->fdd, FDD_WRITE );
+          fdd_read_write_data( d, FDD_WRITE );
         if( f->mf )					/* MFM */
           for( i = 11; i > 0; i-- )	/* write another 11 GAP byte */
-	    fdd_read_write_data( &d->fdd, FDD_WRITE );
-        d->fdd.data = 0x00;
+	    fdd_read_write_data( d, FDD_WRITE );
+        d->data = 0x00;
         for( i = f->mf ? 12 : 6; i > 0; i-- )	/* write 6/12 zero */
-          fdd_read_write_data( &d->fdd, FDD_WRITE );
+          fdd_read_write_data( d, FDD_WRITE );
         crc_preset( f );
         if( f->mf ) {				/* MFM */
-          d->fdd.data = 0xffa1;
+          d->data = 0xffa1;
           for( i = 3; i > 0; i-- ) {		/* write 3 0xa1 with clock mark */
-	    fdd_read_write_data( &d->fdd, FDD_WRITE ); crc_add( f, d );
+	    fdd_read_write_data( d, FDD_WRITE ); crc_add( f, d );
           }
         }
-        d->fdd.data = 0x00fb | ( f->mf ? 0x0000 : 0xff00 );	/* write data mark */
-        fdd_read_write_data( &d->fdd, FDD_WRITE ); crc_add( f, d );
+        d->data = 0x00fb | ( f->mf ? 0x0000 : 0xff00 );	/* write data mark */
+        fdd_read_write_data( d, FDD_WRITE ); crc_add( f, d );
 	
-    	d->fdd.data =  f->data_register[4];	/* write filler byte */
+    	d->data =  f->data_register[4];	/* write filler byte */
 	for( i = f->rlen; i > 0; i-- ) {
-          fdd_read_write_data( &d->fdd, FDD_WRITE ); crc_add( f, d );
+          fdd_read_write_data( d, FDD_WRITE ); crc_add( f, d );
 	}
-        d->fdd.data = f->crc >> 8;
-        fdd_read_write_data( &d->fdd, FDD_WRITE );	/* write crc1 */
-        d->fdd.data = f->crc & 0xff;
-        fdd_read_write_data( &d->fdd, FDD_WRITE );	/* write crc2 */
+        d->data = f->crc >> 8;
+        fdd_read_write_data( d, FDD_WRITE );	/* write crc1 */
+        d->data = f->crc & 0xff;
+        fdd_read_write_data( d, FDD_WRITE );	/* write crc2 */
 
-        d->fdd.data = f->mf ? 0x4e : 0xff;
+        d->data = f->mf ? 0x4e : 0xff;
 	for( i = f->data_register[3]; i > 0; i-- ) {	/* GAP */
-          fdd_read_write_data( &d->fdd, FDD_WRITE );
+          fdd_read_write_data( d, FDD_WRITE );
 	}
         f->data_offset = 0;
 	f->data_register[2]--;		/* prepare next sector */
@@ -1079,9 +1078,9 @@
       }
       if( f->data_register[2] == 0 ) {	/* finish all sector */
 
-        d->fdd.data = f->mf ? 0x4e : 0xff;	/* GAP3 as Intel call this GAP */
-        while( !d->fdd.index )
-          fdd_read_write_data( &d->fdd, FDD_WRITE );
+        d->data = f->mf ? 0x4e : 0xff;	/* GAP3 as Intel call this GAP */
+        while( !d->index )
+          fdd_read_write_data( d, FDD_WRITE );
 
 
 	f->state = UPD_FDC_STATE_RES;	/* end of execution phase */
@@ -1097,21 +1096,21 @@
       return;
     } else if( f->cmd->id == UPD_CMD_WRITE_DATA ) {		/* WRITE DATA */
       f->data_offset++;
-      d->fdd.data = data;
-      fdd_read_write_data( &d->fdd, FDD_WRITE ); crc_add( f, d );
+      d->data = data;
+      fdd_read_write_data( d, FDD_WRITE ); crc_add( f, d );
     
       if( f->data_offset == f->rlen ) {	/* read only rlen byte from host */
-        d->fdd.data = 0x00;
+        d->data = 0x00;
         while( f->data_offset < f->sector_length ) {	/* fill with 0x00 */
-	  fdd_read_write_data( &d->fdd, FDD_READ ); crc_add( f, d );
+	  fdd_read_write_data( d, FDD_READ ); crc_add( f, d );
 	  f->data_offset++;
         }
       }
       if( f->data_offset == f->sector_length ) {	/* write the CRC */
-        d->fdd.data = f->crc >> 8;
-        fdd_read_write_data( &d->fdd, FDD_WRITE );	/* write crc1 */
-        d->fdd.data = f->crc & 0xff;
-        fdd_read_write_data( &d->fdd, FDD_WRITE );	/* write crc2 */
+        d->data = f->crc >> 8;
+        fdd_read_write_data( d, FDD_WRITE );	/* write crc1 */
+        d->data = f->crc & 0xff;
+        fdd_read_write_data( d, FDD_WRITE );	/* write crc2 */
         f->main_status &= ~UPD_FDC_MAIN_DATAREQ;
 	start_write_data( f );
       }
@@ -1118,22 +1117,22 @@
       return;
     } else {						/* SCAN */
       f->data_offset++;
-      fdd_read_write_data( &d->fdd, FDD_READ ); crc_add( f, d );
-      if( f->data_offset == 0 && d->fdd.data == data )	/* `scan hit' */
+      fdd_read_write_data( d, FDD_READ ); crc_add( f, d );
+      if( f->data_offset == 0 && d->data == data )	/* `scan hit' */
         f->status_register[2] |= UPD_FDC_ST2_SCAN_HIT;
 
-      if( d->fdd.data != data )				/* `scan _not_ hit' */
+      if( d->data != data )				/* `scan _not_ hit' */
         f->status_register[2] &= ~UPD_FDC_ST2_SCAN_HIT;
 
-      if( ( f->scan == UPD_SCAN_EQ && d->fdd.data != data ) ||	/* scan not satisfied */
-          ( f->scan == UPD_SCAN_LO && d->fdd.data > data ) ||
-          ( f->scan == UPD_SCAN_HI && d->fdd.data < data ) ) {
+      if( ( f->scan == UPD_SCAN_EQ && d->data != data ) ||	/* scan not satisfied */
+          ( f->scan == UPD_SCAN_LO && d->data > data ) ||
+          ( f->scan == UPD_SCAN_HI && d->data < data ) ) {
         f->status_register[2] |= UPD_FDC_ST2_SCAN_NOT_SAT;
       }
     
       if( f->data_offset == f->sector_length ) {	/* read the CRC */
-	fdd_read_write_data( &d->fdd, FDD_READ ); crc_add( f, d );
-	fdd_read_write_data( &d->fdd, FDD_READ ); crc_add( f, d );
+	fdd_read_write_data( d, FDD_READ ); crc_add( f, d );
+	fdd_read_write_data( d, FDD_READ ); crc_add( f, d );
 	if( f->crc != 0x000 ) {
 	  f->status_register[2] |= UPD_FDC_ST2_DATA_ERROR;
 	  f->status_register[1] |= UPD_FDC_ST1_CRC_ERROR;
@@ -1195,13 +1194,13 @@
 	f->cmd->id != UPD_CMD_INVALID ) {
       f->us = f->data_register[0] & 0x03;
       if( f->current_drive != f->drive[ f->us ] ) {
-        fdd_select( &f->current_drive->fdd, 0 );
+        fdd_select( f->current_drive, 0 );
         f->current_drive = f->drive[ f->us ];
-        fdd_select( &f->current_drive->fdd, 1 );
+        fdd_select( f->current_drive, 1 );
       }
 
       f->hd = ( f->data_register[0] & 0x04 ) >> 2;
-      fdd_set_head( &f->current_drive->fdd, f->hd );
+      fdd_set_head( f->current_drive, f->hd );
 
       /* identify READ_DELETED_DATA/WRITE_DELETED_DATA */
       if( f->cmd->id == UPD_CMD_READ_DATA || 
@@ -1264,9 +1263,9 @@
       f->status_register[3] = f->us + ( f->hd << 2 );
       /*???? the plus3 wiring cause that the double side signal is the
          same as the write protect signal... */
-      f->status_register[3] |= d->fdd.wrprot ? UPD_FDC_ST3_WRPROT : 0;
-      f->status_register[3] |= d->fdd.tr00 ? UPD_FDC_ST3_TR00 : 0;
-      f->status_register[3] |= d->fdd.ready ? UPD_FDC_ST3_READY : 0;
+      f->status_register[3] |= d->wrprot ? UPD_FDC_ST3_WRPROT : 0;
+      f->status_register[3] |= d->tr00 ? UPD_FDC_ST3_TR00 : 0;
+      f->status_register[3] |= d->ready ? UPD_FDC_ST3_READY : 0;
       break;
     case UPD_CMD_SENSE_INT:
       for( i = 0; i < 4; i++ ) {
@@ -1308,7 +1307,7 @@
       break;
     case UPD_CMD_READ_DATA:
     /* Speedlock hack */
-      if( f->speedlock != -1 && !d->fdd.do_read_weak ) {	/* do not conflict with fdd weak read */
+      if( f->speedlock != -1 && !d->do_read_weak ) {	/* do not conflict with fdd weak read */
 	u = ( f->data_register[2] & 0x01 ) + ( f->data_register[1] << 1 ) +
 	    ( f->data_register[3] << 8 );
 	if( f->data_register[3] == f->data_register[5] && u == 0x200 ) {
@@ -1340,7 +1339,7 @@
       break;
 
     case UPD_CMD_WRITE_DATA:
-      if( d->fdd.wrprot ) {
+      if( d->wrprot ) {
         f->status_register[1] |= UPD_FDC_ST1_NOT_WRITEABLE;
         f->status_register[0] |= UPD_FDC_ST0_INT_ABNORM;
 	terminated = 1;
@@ -1354,7 +1353,7 @@
       return;
       break;
     case UPD_CMD_WRITE_ID:			/* FORMAT TRACK */
-      if( d->fdd.wrprot ) {
+      if( d->wrprot ) {
         f->status_register[1] |= UPD_FDC_ST1_NOT_WRITEABLE;
         f->status_register[0] |= UPD_FDC_ST0_INT_ABNORM;
 	terminated = 1;
Index: peripherals/disk/upd_fdc.h
===================================================================
--- peripherals/disk/upd_fdc.h	(revision 5113)
+++ peripherals/disk/upd_fdc.h	(working copy)
@@ -87,14 +87,9 @@
   UPD_INTRQ_SEEK,
 } upd_intrq_t;
 
-typedef struct upd_fdc_drive {
-  fdd_t fdd;			/* floppy disk drive */
-  disk_t disk;			/* the floppy disk itself */
-} upd_fdc_drive;
-
 typedef struct upd_fdc {
-  upd_fdc_drive *current_drive;
-  upd_fdc_drive *drive[4];	/* UPD765 control 4 drives */
+  fdd_t *current_drive;
+  fdd_t *drive[4];		/* UPD765 control 4 drives */
 
   upd_type_t type;		/* UPD765A UPD765B */
   upd_clock_t clock;		/* clock rate ( 4/8 MHz ) */
Index: peripherals/disk/wd_fdc.c
===================================================================
--- peripherals/disk/wd_fdc.c	(revision 5113)
+++ peripherals/disk/wd_fdc.c	(working copy)
@@ -38,7 +38,7 @@
 
 static void statusbar_update( int busy );
 static void crc_preset( wd_fdc *f );
-static void crc_add( wd_fdc *f, wd_fdc_drive *d );
+static void crc_add( wd_fdc *f, fdd_t *d );
 static int read_id( wd_fdc *f );
 static int read_datamark( wd_fdc *f );
 static void wd_fdc_seek_verify( wd_fdc *f );
@@ -62,7 +62,7 @@
 void
 wd_fdc_master_reset( wd_fdc *f )
 {
-  wd_fdc_drive *d = f->current_drive;
+  fdd_t *d = f->current_drive;
 
   f->spin_cycles = 0;
   f->direction = 0;
@@ -69,9 +69,9 @@
   f->head_load = 0;
   if( d ) {
     if( f->flags & WD_FLAG_BETA128 )
-      fdd_motoron( &d->fdd, 0 );
+      fdd_motoron( d, 0 );
     else
-      fdd_head_load( &d->fdd, 0 );
+      fdd_head_load( d, 0 );
   }
   f->read_id = 0;
   if( f->hlt_time > 0 ) f->hlt = 0;
@@ -82,8 +82,8 @@
   f->status_type = WD_FDC_STATUS_TYPE1;
 
   if( d != NULL ) {
-    while( !d->fdd.tr00 )
-      fdd_step( &d->fdd, FDD_STEP_OUT );
+    while( !d->tr00 )
+      fdd_step( d, FDD_STEP_OUT );
   }
 
   f->track_register = 0;
@@ -197,9 +197,9 @@
 }
 
 static void
-crc_add( wd_fdc *f, wd_fdc_drive *d )
+crc_add( wd_fdc *f, fdd_t *d )
 {
-  f->crc = crc_fdc( f->crc, d->fdd.data & 0xff );
+  f->crc = crc_fdc( f->crc, d->data & 0xff );
 }
 
 /* return 0 if found an ID 
@@ -210,7 +210,7 @@
 read_id( wd_fdc *f )
 {
   int i = f->rev;
-  wd_fdc_drive *d = f->current_drive;
+  fdd_t *d = f->current_drive;
 
   f->id_mark = WD_FDC_AM_NONE;
 
@@ -220,48 +220,48 @@
   while( i == f->rev ) {
     crc_preset( f );
     if( f->dden ) {	/* double density (MFM) */
-      fdd_read_write_data( &d->fdd, FDD_READ );
-      if( d->fdd.index ) f->rev--;
+      fdd_read_write_data( d, FDD_READ );
+      if( d->index ) f->rev--;
       crc_add(f, d);
-      if( d->fdd.data == 0xffa1 ) {
-        fdd_read_write_data( &d->fdd, FDD_READ ); crc_add(f, d);
-        if( d->fdd.index ) f->rev--;
-        if( d->fdd.data != 0xffa1 )
+      if( d->data == 0xffa1 ) {
+        fdd_read_write_data( d, FDD_READ ); crc_add(f, d);
+        if( d->index ) f->rev--;
+        if( d->data != 0xffa1 )
           continue;
-        fdd_read_write_data( &d->fdd, FDD_READ ); crc_add(f, d);
-        if( d->fdd.index ) f->rev--;
-        if( d->fdd.data != 0xffa1 )
+        fdd_read_write_data( d, FDD_READ ); crc_add(f, d);
+        if( d->index ) f->rev--;
+        if( d->data != 0xffa1 )
           continue;
       } else {		/* no 0xa1 with missing clock... */
         continue;
       }
     }
-    fdd_read_write_data( &d->fdd, FDD_READ ); crc_add(f, d);
-    if( d->fdd.index ) f->rev--;
+    fdd_read_write_data( d, FDD_READ ); crc_add(f, d);
+    if( d->index ) f->rev--;
     if( f->dden ) {	/* double density (MFM) */
-      if( d->fdd.data != 0x00fe )
+      if( d->data != 0x00fe )
         continue;
     } else {		/* single density (FM) */
-      if( d->fdd.data != 0xfffe )
+      if( d->data != 0xfffe )
         continue;
     }
-    fdd_read_write_data( &d->fdd, FDD_READ ); crc_add(f, d);
-    if( d->fdd.index ) f->rev--;
-    f->id_track = d->fdd.data;
-    fdd_read_write_data( &d->fdd, FDD_READ ); crc_add(f, d);
-    if( d->fdd.index ) f->rev--;
-    f->id_head = d->fdd.data;
-    fdd_read_write_data( &d->fdd, FDD_READ ); crc_add(f, d);
-    if( d->fdd.index ) f->rev--;
-    f->id_sector = d->fdd.data;
-    fdd_read_write_data( &d->fdd, FDD_READ ); crc_add(f, d);
-    if( d->fdd.index ) f->rev--;
-    f->id_length = d->fdd.data;
-    f->sector_length = 0x80 << d->fdd.data; 
-    fdd_read_write_data( &d->fdd, FDD_READ ); crc_add(f, d);
-    if( d->fdd.index ) f->rev--;
-    fdd_read_write_data( &d->fdd, FDD_READ ); crc_add(f, d);
-    if( d->fdd.index ) f->rev--;
+    fdd_read_write_data( d, FDD_READ ); crc_add(f, d);
+    if( d->index ) f->rev--;
+    f->id_track = d->data;
+    fdd_read_write_data( d, FDD_READ ); crc_add(f, d);
+    if( d->index ) f->rev--;
+    f->id_head = d->data;
+    fdd_read_write_data( d, FDD_READ ); crc_add(f, d);
+    if( d->index ) f->rev--;
+    f->id_sector = d->data;
+    fdd_read_write_data( d, FDD_READ ); crc_add(f, d);
+    if( d->index ) f->rev--;
+    f->id_length = d->data;
+    f->sector_length = 0x80 << d->data; 
+    fdd_read_write_data( d, FDD_READ ); crc_add(f, d);
+    if( d->index ) f->rev--;
+    fdd_read_write_data( d, FDD_READ ); crc_add(f, d);
+    if( d->index ) f->rev--;
     if( f->crc != 0x0000 ) {
       f->status_register |= WD_FDC_SR_CRCERR;
       f->id_mark = WD_FDC_AM_ID;
@@ -278,7 +278,7 @@
 static int
 read_datamark( wd_fdc *f )
 {
-  wd_fdc_drive *d = f->current_drive;
+  fdd_t *d = f->current_drive;
   int i;
 
   f->id_mark = WD_FDC_AM_NONE;
@@ -285,11 +285,11 @@
 
   if( f->dden ) {	/* double density (MFM) */
     for( i = 40; i > 0; i-- ) {
-      fdd_read_write_data( &d->fdd, FDD_READ );
-      if( d->fdd.data == 0x4e )		/* read next */
+      fdd_read_write_data( d, FDD_READ );
+      if( d->data == 0x4e )		/* read next */
 	continue;
 
-      if( d->fdd.data == 0x00 )		/* go to PLL sync */
+      if( d->data == 0x00 )		/* go to PLL sync */
 	break;
 
       return 1;				/* something wrong... */
@@ -296,24 +296,24 @@
     } 
     for( ; i > 0; i-- ) {
       crc_preset( f );
-      fdd_read_write_data( &d->fdd, FDD_READ ); crc_add(f, d);
-      if( d->fdd.data == 0x00 )
+      fdd_read_write_data( d, FDD_READ ); crc_add(f, d);
+      if( d->data == 0x00 )
 	continue;
 
-      if( d->fdd.data == 0xffa1 )	/* got to a1 mark */
+      if( d->data == 0xffa1 )	/* got to a1 mark */
 	break;
 
       return 1;
     }
-    for( i = d->fdd.data == 0xffa1 ? 2 : 3; i > 0; i-- ) {
-      fdd_read_write_data( &d->fdd, FDD_READ ); crc_add(f, d);
-      if( d->fdd.data != 0xffa1 )
+    for( i = d->data == 0xffa1 ? 2 : 3; i > 0; i-- ) {
+      fdd_read_write_data( d, FDD_READ ); crc_add(f, d);
+      if( d->data != 0xffa1 )
 	return 1;
     } 
-    fdd_read_write_data( &d->fdd, FDD_READ ); crc_add(f, d);
-    if( d->fdd.data < 0x00f8 || d->fdd.data > 0x00fb )	/* !fb deleted mark */
+    fdd_read_write_data( d, FDD_READ ); crc_add(f, d);
+    if( d->data < 0x00f8 || d->data > 0x00fb )	/* !fb deleted mark */
       return 1;
-    if( d->fdd.data != 0x00fb )
+    if( d->data != 0x00fb )
       f->ddam = 1;
     else
       f->ddam = 0;
@@ -321,11 +321,11 @@
     return 0;
   } else {		/* SD -> FM */
     for( i = 30; i > 0; i-- ) {
-      fdd_read_write_data( &d->fdd, FDD_READ );
-      if( d->fdd.data == 0xff )		/* read next */
+      fdd_read_write_data( d, FDD_READ );
+      if( d->data == 0xff )		/* read next */
 	continue;
 
-      if( d->fdd.data == 0x00 )		/* go to PLL sync */
+      if( d->data == 0x00 )		/* go to PLL sync */
 	break;
 
       return 1;				/* something wrong... */
@@ -332,21 +332,21 @@
     } 
     for( ; i > 0; i-- ) {
       crc_preset( f );
-      fdd_read_write_data( &d->fdd, FDD_READ ); crc_add(f, d);
-      if( d->fdd.data == 0x00 )
+      fdd_read_write_data( d, FDD_READ ); crc_add(f, d);
+      if( d->data == 0x00 )
 	continue;
 
-      if( d->fdd.data >= 0xfff8 && d->fdd.data <= 0xfffb )	/* !fb deleted mark */
+      if( d->data >= 0xfff8 && d->data <= 0xfffb )	/* !fb deleted mark */
 	break;
 
       return 1;
     }
     if( i == 0 ) {
-      fdd_read_write_data( &d->fdd, FDD_READ ); crc_add(f, d);
-      if( d->fdd.data < 0xfff8 || d->fdd.data > 0xfffb )	/* !fb deleted mark */
+      fdd_read_write_data( d, FDD_READ ); crc_add(f, d);
+      if( d->data < 0xfff8 || d->data > 0xfffb )	/* !fb deleted mark */
 	return 1;
     }
-    if( d->fdd.data != 0x00fb )
+    if( d->data != 0x00fb )
       f->ddam = 1;
     else
       f->ddam = 0;
@@ -359,13 +359,13 @@
 libspectrum_byte
 wd_fdc_sr_read( wd_fdc *f )
 {
-  wd_fdc_drive *d = f->current_drive;
+  fdd_t *d = f->current_drive;
 
   wd_fdc_reset_intrq( f );
 
   if( f->status_type == WD_FDC_STATUS_TYPE1 ) {
     f->status_register &= ~WD_FDC_SR_IDX_DRQ;
-    if( !d->fdd.loaded || d->index_pulse )
+    if( !d->loaded || d->index_pulse )
       f->status_register |= WD_FDC_SR_IDX_DRQ;
   }
   if( f->type == WD1773 || f->type == FD1793 ) {
@@ -376,12 +376,13 @@
       f->status_register &= ~WD_FDC_SR_MOTORON; */
 
     if( ( ( f->flags & WD_FLAG_BETA128 ) && f->head_load ) ||
-        ( !( f->flags & WD_FLAG_BETA128 ) && d->fdd.ready ) )
+        ( !( f->flags & WD_FLAG_BETA128 ) && d->ready ) )
       f->status_register &= ~WD_FDC_SR_MOTORON;
     else
       f->status_register |= WD_FDC_SR_MOTORON;
   }
 
+//fprintf(stderr, "wd_fdc_sr_read(%02X) %d\n", f->status_register, d->index_pulse);
   return f->status_register;
 }
 
@@ -425,7 +426,7 @@
 static void
 wd_fdc_seek_verify( wd_fdc *f )
 {
-  wd_fdc_drive *d = f->current_drive;
+  fdd_t *d = f->current_drive;
 
   event_remove_type( fdc_event );
   if( f->type == WD1773 || f->type == FD1793 ) {
@@ -441,7 +442,7 @@
 			   This bit is logical "and" of HLD and "HLT" signals.  */
   }
 
-  if( d->fdd.tr00 )
+  if( d->tr00 )
     f->status_register |= WD_FDC_SR_LOST;
   else
     f->status_register &= ~WD_FDC_SR_LOST;
@@ -455,7 +456,7 @@
 wd_fdc_type_i( wd_fdc *f )
 {
   libspectrum_byte b = f->command_register;
-  wd_fdc_drive *d = f->current_drive;
+  fdd_t *d = f->current_drive;
 
   if( f->state == WD_FDC_STATE_SEEK_DELAY ) {	/* after delay */
     if( ( b & 0x60 ) != 0x00 )			/* STEP/STEP-IN/STEP-OUT */
@@ -487,10 +488,10 @@
     f->track_register += f->direction == FDD_STEP_IN ? 1 : -1;
 
 type_i_noupdate:
-    if( d->fdd.tr00 && f->direction == FDD_STEP_OUT ) {
+    if( d->tr00 && f->direction == FDD_STEP_OUT ) {
       f->track_register = 0;
     } else {
-      fdd_step( &d->fdd, f->direction );
+      fdd_step( d, f->direction );
       f->state = WD_FDC_STATE_SEEK_DELAY;
       event_remove_type( fdc_event );
       event_add_with_data( tstates + f->rates[ b & 0x03 ] * 
@@ -507,9 +508,9 @@
       f->head_load = 1;
       event_remove_type( motor_off_event );
       if( f->flags & WD_FLAG_BETA128 )
-        fdd_motoron( &f->current_drive->fdd, 1 );
+        fdd_motoron( f->current_drive, 1 );
       else
-        fdd_head_load( &f->current_drive->fdd, 1 );
+        fdd_head_load( f->current_drive, 1 );
       event_remove_type( fdc_event );
       event_add_with_data( tstates + 15 * 				/* 15ms */
 		    machine_current->timings.processor_speed / 1000,
@@ -522,7 +523,7 @@
     if( ( f->type == WD1770 || f->type == WD1772 ) &&
 	!( f->status_register & WD_FDC_SR_MOTORON ) ) {
       f->status_register |= WD_FDC_SR_MOTORON;
-      fdd_motoron( &f->current_drive->fdd, 1 );
+      fdd_motoron( f->current_drive, 1 );
       statusbar_update( 1 );
       event_remove_type( fdc_event );
       event_add_with_data( tstates + 12 * 		/* 6 revolution 6 * 200 / 1000 */
@@ -535,7 +536,7 @@
     return;
   }
 
-  if( d->fdd.tr00 )
+  if( d->tr00 )
     f->status_register |= WD_FDC_SR_LOST;
   else
     f->status_register &= ~WD_FDC_SR_LOST;
@@ -549,7 +550,7 @@
 wd_fdc_type_ii_seek( wd_fdc *f )
 {
   libspectrum_byte b = f->command_register;
-  wd_fdc_drive *d = f->current_drive;
+  fdd_t *d = f->current_drive;
   int i;
 
   event_remove_type( fdc_event );
@@ -608,26 +609,26 @@
   } else {
     f->ddam = b & 0x01;
     for( i = 11; i > 0; i-- )	/* "delay" 11 GAP byte */
-      fdd_read_write_data( &d->fdd, FDD_READ );
+      fdd_read_write_data( d, FDD_READ );
     wd_fdc_set_datarq( f );
     f->data_offset = 0;
     if( f->dden )
       for( i = 11; i > 0; i-- )	/* "delay" another 11 GAP byte */
-	fdd_read_write_data( &d->fdd, FDD_READ );
+	fdd_read_write_data( d, FDD_READ );
 
-    d->fdd.data = 0x00;
+    d->data = 0x00;
     for( i = f->dden ? 12 : 6; i > 0; i-- )	/* write 6/12 zero */
-      fdd_read_write_data( &d->fdd, FDD_WRITE );
+      fdd_read_write_data( d, FDD_WRITE );
     crc_preset( f );
     if( f->dden ) {				/* MFM */
-      d->fdd.data = 0xffa1;
+      d->data = 0xffa1;
       for( i = 3; i > 0; i-- ) {		/* write 3 0xa1 with clock mark */
-	fdd_read_write_data( &d->fdd, FDD_WRITE ); crc_add(f, d);
+	fdd_read_write_data( d, FDD_WRITE ); crc_add(f, d);
       }
     }
-    d->fdd.data = ( f->ddam ? 0x00f8 : 0x00fb ) |
+    d->data = ( f->ddam ? 0x00f8 : 0x00fb ) |
     			( f->dden ? 0x0000 : 0xff00 );	/* write data mark */
-    fdd_read_write_data( &d->fdd, FDD_WRITE ); crc_add(f, d);
+    fdd_read_write_data( d, FDD_WRITE ); crc_add(f, d);
   }
   event_remove_type( timeout_event );
   event_add_with_data( tstates + 			/* 5 revolutions: 5 * 200 / 1000 */
@@ -639,7 +640,7 @@
 wd_fdc_type_ii( wd_fdc *f )
 {
   libspectrum_byte b = f->command_register;
-  wd_fdc_drive *d = f->current_drive;
+  fdd_t *d = f->current_drive;
 
   event_remove_type( fdc_event );
   if( f->type == WD1773 || f->type == FD1793 ) {
@@ -652,7 +653,7 @@
   }
 
   if( f->state == WD_FDC_STATE_WRITE ) {
-    if( d->fdd.wrprot ) {
+    if( d->wrprot ) {
       f->status_register |= WD_FDC_SR_WRPROT;
       f->status_register &= ~WD_FDC_SR_BUSY;
       f->state = WD_FDC_STATE_NONE;
@@ -672,7 +673,7 @@
 wd_fdc_type_iii( wd_fdc *f )
 {
   int i;
-  wd_fdc_drive *d = f->current_drive;
+  fdd_t *d = f->current_drive;
 
   event_remove_type( fdc_event );
   if( !f->read_id && ( f->type == WD1773 || f->type == FD1793 ) ) {
@@ -684,7 +685,7 @@
     }
   }
   if( f->state == WD_FDC_STATE_WRITETRACK ) {		/* ----WRITE TRACK---- */
-    if( d->fdd.wrprot ) {
+    if( d->wrprot ) {
       f->status_register |= WD_FDC_SR_WRPROT;
       f->status_register &= ~WD_FDC_SR_BUSY;
       f->state = WD_FDC_STATE_NONE;
@@ -694,10 +695,10 @@
     f->status_register &= ~WD_FDC_SR_WRPROT;
 
     f->data_offset = 0;
-    fdd_wait_index_hole( &d->fdd );
+    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->fdd );
+    fdd_wait_index_hole( d );
     wd_fdc_set_datarq( f );
   } else {						/* ----READID---- */
     if( !f->read_id ) {
@@ -763,13 +764,13 @@
   if( event == motor_off_event ) {
     if( f->type == WD1770 || f->type == WD1772 ) {
       f->status_register &= ~WD_FDC_SR_MOTORON;
-      fdd_motoron( &f->current_drive->fdd, 0 );
+      fdd_motoron( f->current_drive, 0 );
     } else {						/* WD1773/FD1973 */
       f->head_load = 0;
       if( f->flags & WD_FLAG_BETA128 )
-        fdd_motoron( &f->current_drive->fdd, 0 );
+        fdd_motoron( f->current_drive, 0 );
       else
-        fdd_head_load( &f->current_drive->fdd, 0 );
+        fdd_head_load( f->current_drive, 0 );
     }
     statusbar_update( 0 );
     return;
@@ -819,6 +820,32 @@
     wd_fdc_type_iii( f );
 }
 
+/* this chart looks like most close of the reality...
+           !
+        +--+--+
+       /  is   \  no
+      ! MO =  0 !----->----+
+       \   ?   /           !
+        +--+--+            !
+           !               !
++--------------+--------+  !
+!        set MO         !  !
++--------------+--------+  v
+           !               !
+        +--+--+            !
+       /  is   \  no       !
+      ! h  =  0 !----->----+
+       \   ?   /           !
+        +--+--+            !
+           !yes            !
++--------------+--------+  v
+! delay 6 index pulses  !  !
++--------------+--------+  !
+           !               !
+           !-------<-------+
+           !
+*/
+
 static int
 wd_fdc_spinup( wd_fdc *f, libspectrum_byte b )
 {
@@ -828,12 +855,13 @@
     delay = 30;
 
   if( f->type == WD1770 || f->type == WD1772 ) {
-    if( !( b & 0x08 ) &&
-	!( f->status_register & WD_FDC_SR_MOTORON ) ) {
+
+    if( !( f->status_register & WD_FDC_SR_MOTORON ) ) {
       f->status_register |= WD_FDC_SR_MOTORON;
-      fdd_motoron( &f->current_drive->fdd, 1 );
+      fdd_motoron( f->current_drive, 1 );
       statusbar_update( 1 );
-      delay += 6 * 200;
+      if( !( b & 0x08 ) )
+        delay += 6 * 200;
     }
   } else {			/* WD1773/FD1793 */
     event_remove_type( motor_off_event );
@@ -841,17 +869,17 @@
       if( b & 0x08 ) {
 	f->head_load = 1;
         if( f->flags & WD_FLAG_BETA128 )
-          fdd_motoron( &f->current_drive->fdd, 1 );
+          fdd_motoron( f->current_drive, 1 );
         else
-	  fdd_head_load( &f->current_drive->fdd, 1 );
+	  fdd_head_load( f->current_drive, 1 );
 	statusbar_update( 1 );
       } else {
 	f->head_load = 0;
         if( f->hlt_time > 0 ) f->hlt = 0;		/* reset the trigger */
         if( f->flags & WD_FLAG_BETA128 )
-          fdd_motoron( &f->current_drive->fdd, 0 );
+          fdd_motoron( f->current_drive, 0 );
         else
-	  fdd_head_load( &f->current_drive->fdd, 0 );
+	  fdd_head_load( f->current_drive, 0 );
 	statusbar_update( 0 );
       }
       return 0;
@@ -858,9 +886,9 @@
     } else {
       f->head_load = 1;
       if( f->flags & WD_FLAG_BETA128 )
-        fdd_motoron( &f->current_drive->fdd, 1 );
+        fdd_motoron( f->current_drive, 1 );
       else
-        fdd_head_load( &f->current_drive->fdd, 1 );
+        fdd_head_load( f->current_drive, 1 );
       statusbar_update( 1 );
       if( f->hlt_time > 0 )
         delay += f->hlt_time;
@@ -879,7 +907,7 @@
 void
 wd_fdc_cr_write( wd_fdc *f, libspectrum_byte b )
 {
-  wd_fdc_drive *d = f->current_drive;
+  fdd_t *d = f->current_drive;
 
   wd_fdc_reset_intrq( f );
 
@@ -896,11 +924,13 @@
     else if( b & 0x04 )
       d->index_interrupt = 1;
 
-    if( d->fdd.tr00 )
+    if( d->tr00 )
       f->status_register |= WD_FDC_SR_LOST;
     else
       f->status_register &= ~WD_FDC_SR_LOST;
 
+    wd_fdc_spinup( f, b & 0xf7 ); /* spinup motor, but we do not have a 'h' bit!  */
+
     return;
   }
 
@@ -927,7 +957,7 @@
   } else if( !( b & 0x40 ) ) {                  /* Type II */
     if( f->type == WD1773 || f->type == FD1793 ) {
       if( ( ( f->flags & WD_FLAG_BETA128 ) && !f->head_load ) ||
-        ( !( f->flags & WD_FLAG_BETA128 ) && !d->fdd.ready ) ) {
+        ( !( f->flags & WD_FLAG_BETA128 ) && !d->ready ) ) {
         f->status_register &= ~WD_FDC_SR_BUSY;
         f->state = WD_FDC_STATE_NONE;
         wd_fdc_set_intrq( f );
@@ -951,7 +981,7 @@
   } else if( ( b & 0x30 ) != 0x10 ) {           /* Type III */
     if( f->type == WD1773 || f->type == FD1793 ) {
       if( ( ( f->flags & WD_FLAG_BETA128 ) && !f->head_load ) ||
-        ( !( f->flags & WD_FLAG_BETA128 ) && !d->fdd.ready ) ) {
+        ( !( f->flags & WD_FLAG_BETA128 ) && !d->ready ) ) {
         f->status_register &= ~WD_FDC_SR_BUSY;
         f->state = WD_FDC_STATE_NONE;
         wd_fdc_set_intrq( f );
@@ -999,7 +1029,7 @@
 libspectrum_byte
 wd_fdc_dr_read( wd_fdc *f )
 {
-  wd_fdc_drive *d = f->current_drive;
+  fdd_t *d = f->current_drive;
 
   if( f->flags & WD_FLAG_OPUS &&
 	f->status_register & WD_FDC_SR_BUSY )
@@ -1007,8 +1037,8 @@
 
   if( f->state == WD_FDC_STATE_READ ) {
     f->data_offset++;				/* count read bytes */
-    fdd_read_write_data( &d->fdd, FDD_READ ); crc_add(f, d); /* read a byte */
-    if( d->fdd.data > 0xff ) {			/* no data */
+    fdd_read_write_data( d, FDD_READ ); crc_add(f, d); /* read a byte */
+    if( d->data > 0xff ) {			/* no data */
       f->status_register |= WD_FDC_SR_RNF;
       f->status_register &= ~WD_FDC_SR_BUSY;
       f->status_type = WD_FDC_STATUS_TYPE2;
@@ -1016,10 +1046,10 @@
       wd_fdc_set_intrq( f );
       wd_fdc_reset_datarq( f );
     } else {
-      f->data_register = d->fdd.data;
+      f->data_register = d->data;
       if( f->data_offset == f->sector_length ) {	/* read the CRC */
-	fdd_read_write_data( &d->fdd, FDD_READ ); crc_add(f, d);
-	fdd_read_write_data( &d->fdd, FDD_READ ); crc_add(f, d);
+	fdd_read_write_data( d, FDD_READ ); crc_add(f, d);
+	fdd_read_write_data( d, FDD_READ ); crc_add(f, d);
 
 	/* FIXME: make this per-FDC */
 	event_remove_type( timeout_event );	/* clear the timeout */
@@ -1080,9 +1110,9 @@
     f->data_offset++;
   } else if( f->state == WD_FDC_STATE_READTRACK ) {
 						/* unformatted/out of track looks like 1x 0x00 */
-    fdd_read_write_data( &d->fdd, FDD_READ );	/* read a byte and give to host */
-    f->data_register = d->fdd.data & 0x00ff;	/* drop clock marks */
-    if( d->fdd.index ) {
+    fdd_read_write_data( d, FDD_READ );	/* read a byte and give to host */
+    f->data_register = d->data & 0x00ff;	/* drop clock marks */
+    if( d->index ) {
       event_remove_type( timeout_event );	/* clear the timeout */
       f->status_register &= ~WD_FDC_SR_BUSY;
       f->status_type = WD_FDC_STATUS_TYPE2;
@@ -1103,20 +1133,20 @@
 void
 wd_fdc_dr_write( wd_fdc *f, libspectrum_byte b )
 {
-  wd_fdc_drive *d = f->current_drive;
+  fdd_t *d = f->current_drive;
 
   f->data_register = b;
   if( f->state == WD_FDC_STATE_WRITE ) {
-    d->fdd.data = b;
+    d->data = b;
     f->data_offset++;				/* count bytes read */
-    fdd_read_write_data( &d->fdd, FDD_WRITE ); crc_add(f, d);
+    fdd_read_write_data( d, FDD_WRITE ); crc_add(f, d);
     if( f->data_offset == f->sector_length ) {	/* write the CRC */
-      d->fdd.data = f->crc >> 8;
-      fdd_read_write_data( &d->fdd, FDD_WRITE );	/* write crc1 */
-      d->fdd.data = f->crc & 0xff;
-      fdd_read_write_data( &d->fdd, FDD_WRITE );	/* write crc2 */
-      d->fdd.data = 0xff;
-      fdd_read_write_data( &d->fdd, FDD_WRITE );	/* write 1 byte of ff? */
+      d->data = f->crc >> 8;
+      fdd_read_write_data( d, FDD_WRITE );	/* write crc1 */
+      d->data = f->crc & 0xff;
+      fdd_read_write_data( d, FDD_WRITE );	/* write crc2 */
+      d->data = 0xff;
+      fdd_read_write_data( d, FDD_WRITE );	/* write 1 byte of ff? */
 
       event_remove_type( timeout_event );	/* clear the timeout */
 
@@ -1139,38 +1169,38 @@
       }
     }
   } else if( f->state == WD_FDC_STATE_WRITETRACK ) {
-    d->fdd.data = b;
+    d->data = b;
     if( f->dden ) {			/* MFM */
       if( b == 0xf7 ) {			/* CRC */
-	d->fdd.data = f->crc >> 8;
-	fdd_read_write_data( &d->fdd, FDD_WRITE );	/* write crc1 */
-	d->fdd.data = f->crc & 0xff;
+	d->data = f->crc >> 8;
+	fdd_read_write_data( d, FDD_WRITE );	/* write crc1 */
+	d->data = f->crc & 0xff;
       } else if ( b == 0xf5 ) {
-	d->fdd.data = 0xffa1;		/* and preset CRC */
+	d->data = 0xffa1;		/* and preset CRC */
 	f->crc = 0xcdb4;		/* 3x crc = crc_fdc( crc, 0xa1 )???? */
       } else if ( b == 0xf6 ) {
-	d->fdd.data = 0xffc2;
+	d->data = 0xffc2;
       } else {
 	crc_add(f, d);
       }
     } else {				/* FM */
       if( b == 0xf7 ) {			/* CRC */
-	d->fdd.data = f->crc >> 8;
-	fdd_read_write_data( &d->fdd, FDD_WRITE );	/* write crc1 */
-	d->fdd.data = f->crc & 0xff;
+	d->data = f->crc >> 8;
+	fdd_read_write_data( d, FDD_WRITE );	/* write crc1 */
+	d->data = f->crc & 0xff;
       } else if ( b == 0xfe || ( b >= 0xf8 && b <= 0xfb ) ) {
 	crc_preset( f );		/* preset CRC */
 	crc_add(f, d);
-	d->fdd.data |= 0xff00;
+	d->data |= 0xff00;
       } else if ( b == 0xfc ) {
-	d->fdd.data |= 0xff00;
+	d->data |= 0xff00;
       } else {
 	crc_add(f, d);
       }
     }
-    fdd_read_write_data( &d->fdd, FDD_WRITE );	/* write a byte */
+    fdd_read_write_data( d, FDD_WRITE );	/* write a byte */
 
-    if( d->fdd.index ) {
+    if( d->index ) {
       event_remove_type( timeout_event );	/* clear the timeout */
       f->status_register &= ~WD_FDC_SR_BUSY;
       f->state = WD_FDC_STATE_NONE;
Index: peripherals/disk/wd_fdc.h
===================================================================
--- peripherals/disk/wd_fdc.h	(revision 5113)
+++ peripherals/disk/wd_fdc.h	(working copy)
@@ -59,16 +59,8 @@
 extern int wd_fdc_index_pulse;
 extern int wd_fdc_index_interrupt;
 
-typedef struct wd_fdc_drive {
-  fdd_t fdd;			/* floppy disk drive */
-  disk_t disk;			/* the floppy disk itself */
-  int index_pulse;
-  int index_interrupt;
-
-} wd_fdc_drive;
-
 typedef struct wd_fdc {
-  wd_fdc_drive *current_drive;
+  fdd_t *current_drive;
 
   wd_type_t type;		/* WD1770, WD1772, WD1773 */
 
Index: ui/uimedia.h
===================================================================
--- ui/uimedia.h	(revision 5113)
+++ ui/uimedia.h	(working copy)
@@ -52,7 +52,6 @@
   ui_media_drive_insert_hook_fn insert_hook;
   ui_media_drive_autoload_hook_fn autoload_hook;
   struct fdd_t *fdd;
-  struct disk_t *disk;
 } ui_media_drive_info_t;
 
 int ui_media_drive_register( ui_media_drive_info_t *drive );
Index: uimedia.c
===================================================================
--- uimedia.c	(revision 5113)
+++ uimedia.c	(working copy)
@@ -187,10 +187,10 @@
 {
   int error;
 
-  drive->disk->type = DISK_TYPE_NONE;
+  drive->fdd->disk.type = DISK_TYPE_NONE;
   if( filename == NULL )
-    filename = drive->disk->filename; /* write over original file */
-  error = disk_write( drive->disk, filename );
+    filename = drive->fdd->disk.filename; /* write over original file */
+  error = disk_write( &drive->fdd->disk, filename );
 
   if( error != DISK_OK ) {
     ui_error( UI_ERROR_ERROR, "couldn't write '%s' file: %s", filename,
@@ -198,9 +198,9 @@
     return 1;
   }
 
-  if( drive->disk->filename && strcmp( filename, drive->disk->filename ) ) {
-    free( drive->disk->filename );
-    drive->disk->filename = utils_safe_strdup( filename );
+  if( drive->fdd->disk.filename && strcmp( filename, drive->fdd->disk.filename ) ) {
+    free( drive->fdd->disk.filename );
+    drive->fdd->disk.filename = utils_safe_strdup( filename );
   }
   return 0;
 }
@@ -212,9 +212,9 @@
   int err;
   char *filename = NULL, title[80];
 
-  if( drive->disk->type == DISK_TYPE_NONE )
+  if( drive->fdd->disk.type == DISK_TYPE_NONE )
     return 0;
-  if( drive->disk->filename == NULL )
+  if( drive->fdd->disk.filename == NULL )
     saveas = 1;
 
   fuse_emulation_pause();
@@ -237,7 +237,7 @@
   if( err )
     return 1;
 
-  drive->disk->dirty = 0;
+  drive->fdd->disk.dirty = 0;
   return 0;
 }
 
@@ -255,10 +255,10 @@
 static int
 drive_eject( const ui_media_drive_info_t *drive )
 {
-  if( drive->disk->type == DISK_TYPE_NONE )
+  if( !drive->fdd->loaded || drive->fdd->disk.type == DISK_TYPE_NONE )
     return 0;
 
-  if( drive->disk->dirty ) {
+  if( drive->fdd->disk.dirty ) {
 
     ui_confirm_save_t confirm = ui_confirm_save(
       "%s has been modified.\n"
@@ -280,7 +280,7 @@
   }
 
   fdd_unload( drive->fdd );
-  disk_close( drive->disk );
+  disk_close( &drive->fdd->disk );
   ui_media_drive_update_menus( drive, UI_MEDIA_DRIVE_UPDATE_EJECT );
   return 0;
 }
@@ -328,7 +328,7 @@
   }
 
   if( filename ) {
-    error = disk_open( drive->disk, filename, 0,
+    error = disk_open( &drive->fdd->disk, filename, 0,
                        DISK_TRY_MERGE( drive->fdd->fdd_heads ) );
     if( error != DISK_OK ) {
       ui_error( UI_ERROR_ERROR, "Failed to open disk image: %s",
@@ -337,7 +337,7 @@
     }
   } else {
     dt = drive->get_params();
-    error = disk_new( drive->disk, dt->heads, dt->cylinders, DISK_DENS_AUTO,
+    error = disk_new( &drive->fdd->disk, dt->heads, dt->cylinders, DISK_DENS_AUTO,
                       DISK_UDI );
     if( error != DISK_OK ) {
       ui_error( UI_ERROR_ERROR, "Failed to create disk image: %s",
@@ -351,7 +351,7 @@
       return 1;
   }
 
-  fdd_load( drive->fdd, drive->disk, 0 );
+  fdd_load( drive->fdd, 0 );
 
   /* Set the 'eject' item active */
   ui_media_drive_update_menus( drive, UI_MEDIA_DRIVE_UPDATE_ALL );
