Esempio n. 1
0
static int machine_add_machine( int (*init_function)( fuse_machine_info *machine ) )
{
  fuse_machine_info *machine;
  int error;

  machine_count++;

  machine_types =
    libspectrum_realloc( machine_types,
                         machine_count * sizeof( fuse_machine_info* ) );

  machine_types[ machine_count - 1 ] = malloc( sizeof( fuse_machine_info ) );
  if( !machine_types[ machine_count - 1 ] ) {
    ui_error( UI_ERROR_ERROR, "out of memory at %s:%d", __FILE__, __LINE__ );
    return 1;
  }

  machine = machine_types[ machine_count - 1 ];

  error = init_function( machine ); if( error ) return error;

  machine_set_const_timings( machine );

  machine->capabilities = libspectrum_machine_capabilities( machine->machine );

  return 0;
}
Esempio n. 2
0
static int
machine_select_machine( fuse_machine_info *machine )
{
  int width, height, i;
  int capabilities;

  machine_current = machine;

  settings_set_string( &settings_current.start_machine, machine->id );
  
  tstates = 0;

  /* Reset the event stack */
  event_reset();
  if( event_add( 0, timer_event ) ) return 1;
  if( event_add( machine->timings.tstates_per_frame, spectrum_frame_event ) )
    return 1;

  sound_end();

  if( uidisplay_end() ) return 1;

  capabilities = libspectrum_machine_capabilities( machine->machine );

  /* Set screen sizes here */
  if( capabilities & LIBSPECTRUM_MACHINE_CAPABILITY_TIMEX_VIDEO ) {
    width = DISPLAY_SCREEN_WIDTH;
    height = 2*DISPLAY_SCREEN_HEIGHT;
  } else {
    width = DISPLAY_ASPECT_WIDTH;
    height = DISPLAY_SCREEN_HEIGHT;
  }

  if( uidisplay_init( width, height ) ) return 1;

  sound_init( settings_current.sound_device );

  /* Mark RAM as not-present/read-only. The machine's reset function will
   * mark available pages as present/writeable.
   */
  for( i = 0; i < 2 * SPECTRUM_RAM_PAGES; i++ )
    memory_map_ram[i].writable = 0;

  /* Do a hard reset */
  if( machine_reset( 1 ) ) return 1;

  /* And the dock menu item */
  if( capabilities & LIBSPECTRUM_MACHINE_CAPABILITY_TIMEX_DOCK ) {
    ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 0 );
  }

  /* Reset any dialogue boxes etc. which contain machine-dependent state */
  ui_widgets_reset();

  return 0;
}
Esempio n. 3
0
static int
machine_select_machine( fuse_machine_info *machine )
{
  int width, height;
  int capabilities;

  machine_current = machine;

  settings_set_string( &settings_current.start_machine, machine->id );
  
  tstates = 0;

  /* Reset the event stack */
  event_reset();
  event_add( 0, timer_event );
  event_add( machine->timings.tstates_per_frame, spectrum_frame_event );

  sound_end();

  if( uidisplay_end() ) return 1;

  capabilities = libspectrum_machine_capabilities( machine->machine );

  /* Set screen sizes here */
  if( capabilities & LIBSPECTRUM_MACHINE_CAPABILITY_TIMEX_VIDEO ) {
    width = DISPLAY_SCREEN_WIDTH;
    height = 2*DISPLAY_SCREEN_HEIGHT;
  } else {
    width = DISPLAY_ASPECT_WIDTH;
    height = DISPLAY_SCREEN_HEIGHT;
  }

  if( uidisplay_init( width, height ) ) return 1;

  sound_init( settings_current.sound_device );

  /* Do a hard reset */
  if( machine_reset( 1 ) ) return 1;

  /* And the dock menu item */
  if( capabilities & LIBSPECTRUM_MACHINE_CAPABILITY_TIMEX_DOCK ) {
    ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 0 );
  }

  /* Reset any dialogue boxes etc. which contain machine-dependent state */
  ui_widgets_reset();

  return 0;
}
Esempio n. 4
0
int
dck_insert( const char *filename )
{
  if ( !( libspectrum_machine_capabilities( machine_current->machine ) &
	  LIBSPECTRUM_MACHINE_CAPABILITY_TIMEX_DOCK ) ) {
    ui_error( UI_ERROR_ERROR, "This machine does not support the dock" );
    return 1;
  }

  settings_set_string( &settings_current.dck_file, filename );

  machine_reset( 0 );

  return 0;
}
Esempio n. 5
0
void
dck_eject( void )
{
  if ( !( libspectrum_machine_capabilities( machine_current->machine ) &
	  LIBSPECTRUM_MACHINE_CAPABILITY_TIMEX_DOCK ) ) {
    ui_error( UI_ERROR_ERROR, "This machine does not support the dock" );
    return;
  }

  if( settings_current.dck_file ) libspectrum_free( settings_current.dck_file );
  settings_current.dck_file = NULL;

  dck_active = 0;

  ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 0 );

  machine_reset( 0 );
}
Esempio n. 6
0
static int machine_add_machine( int (*init_function)( fuse_machine_info *machine ) )
{
  fuse_machine_info *machine;
  int error;

  machine_count++;

  machine_types =
    libspectrum_renew( fuse_machine_info *, machine_types, machine_count );

  machine_types[ machine_count - 1 ] = libspectrum_new( fuse_machine_info, 1 );
  machine = machine_types[ machine_count - 1 ];

  error = init_function( machine ); if( error ) return error;

  machine_set_const_timings( machine );

  machine->capabilities = libspectrum_machine_capabilities( machine->machine );

  return 0;
}
Esempio n. 7
0
void
tape_next_edge( libspectrum_dword last_tstates, int type, void *user_data )
{
  libspectrum_error libspec_error;
  libspectrum_tape_block *block;

  libspectrum_dword edge_tstates;
  int flags;

  /* If the tape's not playing, just return */
  if( ! tape_playing ) return;

  /* Get the time until the next edge */
  libspec_error = libspectrum_tape_get_next_edge( &edge_tstates, &flags,
						  tape );
  if( libspec_error != LIBSPECTRUM_ERROR_NONE ) return;

  /* Invert the microphone state */
  if( edge_tstates ||
      !( flags & LIBSPECTRUM_TAPE_FLAGS_NO_EDGE ) ||
      ( flags & ( LIBSPECTRUM_TAPE_FLAGS_STOP |
                  LIBSPECTRUM_TAPE_FLAGS_LEVEL_LOW |
                  LIBSPECTRUM_TAPE_FLAGS_LEVEL_HIGH ) ) ) {

    if( flags & LIBSPECTRUM_TAPE_FLAGS_NO_EDGE ) {
      /* Do nothing */
    } else if( flags & LIBSPECTRUM_TAPE_FLAGS_LEVEL_LOW ) {
      tape_microphone = 0;
    } else if( flags & LIBSPECTRUM_TAPE_FLAGS_LEVEL_HIGH ) {
      tape_microphone = 1;
    } else {
      tape_microphone = !tape_microphone;
    }
  }

  sound_beeper( last_tstates, tape_microphone );

  /* If we've been requested to stop the tape, do so and then
     return without stacking another edge */
  if( ( flags & LIBSPECTRUM_TAPE_FLAGS_STOP ) ||
      ( ( flags & LIBSPECTRUM_TAPE_FLAGS_STOP48 ) && 
	( !( libspectrum_machine_capabilities( machine_current->machine ) &
	     LIBSPECTRUM_MACHINE_CAPABILITY_128_MEMORY
	   )
	)
      )
    )
  {
    tape_stop();
    return;
  }

  /* If that was the end of a block, update the browser */
  if( flags & LIBSPECTRUM_TAPE_FLAGS_BLOCK ) {

    ui_tape_browser_update( UI_TAPE_BROWSER_SELECT_BLOCK, NULL );

    /* If the tape was started automatically, tape traps are active
       and the new block is a ROM loader, stop the tape and return
       without putting another event into the queue */
    block = libspectrum_tape_current_block( tape );
    if( tape_autoplay && settings_current.tape_traps &&
	libspectrum_tape_block_type( block ) == LIBSPECTRUM_TAPE_BLOCK_ROM
      ) {
      tape_stop();
      return;
    }
  }

  /* Otherwise, put this into the event queue; remember that this edge
     should occur 'edge_tstates' after the last edge, not after the
     current time (these will be slightly different as we only process
     events between instructions). */
  event_add( last_tstates + edge_tstates, tape_edge_event );

  /* Store length flags for acceleration purposes */
  loader_set_acceleration_flags( flags );
}