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; }
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; }
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; }
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; }
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 ); }
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; }
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 ); }