int divide_init( void ) { int error, i; divide_idechn0 = libspectrum_ide_alloc( LIBSPECTRUM_IDE_DATA16 ); divide_idechn1 = libspectrum_ide_alloc( LIBSPECTRUM_IDE_DATA16 ); ui_menu_activate( UI_MENU_ITEM_MEDIA_IDE_DIVIDE_MASTER_EJECT, 0 ); ui_menu_activate( UI_MENU_ITEM_MEDIA_IDE_DIVIDE_SLAVE_EJECT, 0 ); if( settings_current.divide_master_file ) { error = libspectrum_ide_insert( divide_idechn0, LIBSPECTRUM_IDE_MASTER, settings_current.divide_master_file ); if( error ) return error; ui_menu_activate( UI_MENU_ITEM_MEDIA_IDE_DIVIDE_MASTER_EJECT, 1 ); } if( settings_current.divide_slave_file ) { error = libspectrum_ide_insert( divide_idechn0, LIBSPECTRUM_IDE_SLAVE, settings_current.divide_slave_file ); if( error ) return error; ui_menu_activate( UI_MENU_ITEM_MEDIA_IDE_DIVIDE_SLAVE_EJECT, 1 ); } module_register( ÷_module_info ); for( i = 0; i < 2; i++ ) divide_memory_map_romcs[i].bank = MEMORY_BANK_ROMCS; if( periph_register_paging_events( event_type_string, &page_event, &unpage_event ) ) return 1; return 0; }
static int start_playback( libspectrum_rzx *rzx ) { int error; libspectrum_snap *snap; error = libspectrum_rzx_start_playback( rzx, 0, &snap ); if( error ) return error; if( snap ) { error = snapshot_copy_from( snap ); if( error ) return error; } /* End of frame will now be generated by the RZX code */ event_remove_type( spectrum_frame_event ); /* Add a sentinel event to prevent tstates overrun (bug #1057471) */ event_add( RZX_SENTINEL_TIME, sentinel_event ); tstates = libspectrum_rzx_tstates( rzx ); rzx_instruction_count = libspectrum_rzx_instructions( rzx ); rzx_playback = 1; counter_reset(); ui_menu_activate( UI_MENU_ITEM_RECORDING, 1 ); ui_menu_activate( UI_MENU_ITEM_RECORDING_ROLLBACK, 0 ); return 0; }
int zxcf_init( void ) { int error; last_memctl = 0x00; zxcf_idechn = libspectrum_ide_alloc( LIBSPECTRUM_IDE_DATA16 ); ui_menu_activate( UI_MENU_ITEM_MEDIA_IDE_ZXCF_EJECT, 0 ); if( settings_current.zxcf_pri_file ) { error = libspectrum_ide_insert( zxcf_idechn, LIBSPECTRUM_IDE_MASTER, settings_current.zxcf_pri_file ); if( error ) return error; ui_menu_activate( UI_MENU_ITEM_MEDIA_IDE_ZXCF_EJECT, 1 ); } module_register( &zxcf_module_info ); if( periph_register_paging_events( event_type_string, &page_event, &unpage_event ) ) return 1; return 0; }
static int zxcf_init( void *context ) { int error, i; last_memctl = 0x00; zxcf_idechn = libspectrum_ide_alloc( LIBSPECTRUM_IDE_DATA16 ); ui_menu_activate( UI_MENU_ITEM_MEDIA_IDE_ZXCF_EJECT, 0 ); if( settings_current.zxcf_pri_file ) { error = libspectrum_ide_insert( zxcf_idechn, LIBSPECTRUM_IDE_MASTER, settings_current.zxcf_pri_file ); if( error ) return error; ui_menu_activate( UI_MENU_ITEM_MEDIA_IDE_ZXCF_EJECT, 1 ); } module_register( &zxcf_module_info ); zxcf_memory_source = memory_source_register( "ZXCF" ); for( i = 0; i < MEMORY_PAGES_IN_16K; i++ ) zxcf_memory_map_romcs[i].source = zxcf_memory_source; periph_register( PERIPH_TYPE_ZXCF, &zxcf_periph ); periph_register_paging_events( event_type_string, &page_event, &unpage_event ); return 0; }
static void start_recording( libspectrum_rzx *rzx, int competition_mode ) { libspectrum_rzx_start_input( rzx, tstates ); counter_reset(); rzx_in_count = 0; autosave_frame_count = 0; rzx_recording = 1; ui_menu_activate( UI_MENU_ITEM_RECORDING, 1 ); if( competition_mode ) { if( !libspectrum_gcrypt_version() ) ui_error( UI_ERROR_WARNING, "gcrypt not available: recording will NOT be signed" ); settings_current.emulation_speed = 100; rzx_competition_mode = 1; } else { ui_menu_activate( UI_MENU_ITEM_RECORDING_ROLLBACK, 1 ); rzx_competition_mode = 0; } }
static void didaktik_reset( int hard_reset ) { int i; didaktik80_active = 0; didaktik80_available = 0; ui_menu_activate( UI_MENU_ITEM_MACHINE_DIDAKTIK80_SNAP, 0 ); if( !periph_is_active( PERIPH_TYPE_DIDAKTIK80 ) ) { return; } if( machine_load_rom_bank( didaktik_memory_map_romcs_rom, 0, settings_current.rom_didaktik80, settings_default.rom_didaktik80, ROM_SIZE ) ) { settings_current.didaktik80 = 0; periph_activate_type( PERIPH_TYPE_DIDAKTIK80, 0 ); return; } ui_menu_activate( UI_MENU_ITEM_MACHINE_DIDAKTIK80_SNAP, 1 ); for( i = 0; i < MEMORY_PAGES_IN_2K; i++ ) { struct memory_page *page = &didaktik_memory_map_romcs_ram[ i ]; page->page = ram + i * MEMORY_PAGE_SIZE; page->offset = i * MEMORY_PAGE_SIZE; page->writable = 1; } machine_current->ram.romcs = 0; aux_register = 0; didaktik80_available = 1; if( hard_reset ) memset( ram, 0, sizeof( ram ) ); wd_fdc_master_reset( didaktik_fdc ); for( i = 0; i < DIDAKTIK80_NUM_DRIVES; i++ ) { ui_media_drive_update_menus( &didaktik_ui_drives[ i ], UI_MEDIA_DRIVE_UPDATE_ALL ); } didaktik_fdc->current_drive = &didaktik_drives[ 0 ]; fdd_select( &didaktik_drives[ 0 ], 1 ); fdd_select( &didaktik_drives[ 1 ], 0 ); machine_current->memory_map(); }
int rzx_stop_recording( void ) { libspectrum_byte *buffer; size_t length; libspectrum_error libspec_error; int error; if( !rzx_recording ) return 0; /* Stop recording data */ rzx_recording = 0; if( settings_current.movie_stop_after_rzx ) movie_stop(); /* Embed final snapshot */ if( !rzx_competition_mode ) rzx_add_snap( rzx, 0 ); libspectrum_free( rzx_in_bytes ); rzx_in_bytes = NULL; rzx_in_allocated = 0; ui_menu_activate( UI_MENU_ITEM_RECORDING, 0 ); ui_menu_activate( UI_MENU_ITEM_RECORDING_ROLLBACK, 0 ); libspectrum_creator_set_competition_code( fuse_creator, settings_current.competition_code ); length = 0; buffer = NULL; libspec_error = libspectrum_rzx_write( &buffer, &length, rzx, LIBSPECTRUM_ID_UNKNOWN, fuse_creator, settings_current.rzx_compression, rzx_competition_mode ? &rzx_key : NULL ); if( libspec_error != LIBSPECTRUM_ERROR_NONE ) { libspectrum_free( rzx_filename ); libspectrum_rzx_free( rzx ); return libspec_error; } error = utils_write_file( rzx_filename, buffer, length ); libspectrum_free( rzx_filename ); if( error ) { libspectrum_free( buffer ); libspectrum_rzx_free( rzx ); return error; } libspectrum_free( buffer ); libspec_error = libspectrum_rzx_free( rzx ); if( libspec_error != LIBSPECTRUM_ERROR_NONE ) return libspec_error; return 0; }
int ide_eject( libspectrum_ide_channel *chn, libspectrum_ide_unit unit, int (*commit_fn)( libspectrum_ide_unit unit ), char **setting, ui_menu_item item ) { int error; if( libspectrum_ide_dirty( chn, unit ) ) { ui_confirm_save_t confirm = ui_confirm_save( "Hard disk has been modified.\nDo you want to save it?" ); switch( confirm ) { case UI_CONFIRM_SAVE_SAVE: error = commit_fn( unit ); if( error ) return error; break; case UI_CONFIRM_SAVE_DONTSAVE: break; case UI_CONFIRM_SAVE_CANCEL: return 1; } } libspectrum_free( *setting ); *setting = NULL; error = libspectrum_ide_eject( chn, unit ); if( error ) return error; error = ui_menu_activate( item, 0 ); if( error ) return error; return 0; }
int tape_record_start( void ) { int error; /* sample rate will be 44.1KHz */ rec_state.tstates_per_sample = machine_current->timings.processor_speed/44100; rec_state.tape_buffer_size = 8192; rec_state.tape_buffer = malloc(rec_state.tape_buffer_size); rec_state.tape_buffer_used = 0; /* start scheduling events that record into a buffer that we start allocating here */ error = event_add( tstates + rec_state.tstates_per_sample, record_event ); if( error ) return error; rec_state.last_level = ula_tape_level(); rec_state.last_level_count = 1; tape_recording = 1; /* Also want to disable other tape actions */ ui_menu_activate( UI_MENU_ITEM_TAPE_RECORDING, 1 ); 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; }
void ui_menu_disk_update( void ) { int drives_avail; drives_avail = ui_media_drive_any_available(); /* Set the disk menu items and statusbar appropriately */ if( drives_avail ) { ui_menu_activate( UI_MENU_ITEM_MEDIA_DISK, 1 ); ui_statusbar_update( UI_STATUSBAR_ITEM_DISK, UI_STATUSBAR_STATE_INACTIVE ); } else { ui_menu_activate( UI_MENU_ITEM_MEDIA_DISK, 0 ); ui_statusbar_update( UI_STATUSBAR_ITEM_DISK, UI_STATUSBAR_STATE_NOT_AVAILABLE ); } ui_media_drive_update_parent_menus(); }
int rzx_stop_playback( int add_interrupt ) { libspectrum_error libspec_error; rzx_playback = 0; if( settings_current.movie_stop_after_rzx ) movie_stop(); ui_menu_activate( UI_MENU_ITEM_RECORDING, 0 ); ui_menu_activate( UI_MENU_ITEM_RECORDING_ROLLBACK, 0 ); event_remove_type( sentinel_event ); /* We've now finished with the RZX file, so add an end of frame event if we've been requested to do so; we don't if we just run out of frames, as this occurs just before a normal end of frame and everything works normally as rzx_playback is now zero again */ if( add_interrupt ) { event_add( machine_current->timings.tstates_per_frame, spectrum_frame_event ); /* We're no longer doing RZX playback, so tstates now be <= the normal frame count */ if( tstates > machine_current->timings.tstates_per_frame ) tstates = machine_current->timings.tstates_per_frame; } else { /* Ensure that tstates will be zero after it is reduced in spectrum_frame() */ tstates = machine_current->timings.tstates_per_frame; } libspec_error = libspectrum_rzx_free( rzx ); if( libspec_error != LIBSPECTRUM_ERROR_NONE ) return libspec_error; debugger_event( end_event ); 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; }
void profile_start( void ) { memset( total_tstates, 0, sizeof( total_tstates ) ); profile_active = 1; init_profiling_counters(); /* Schedule an event to ensure that the main z80 emulation loop recognises profiling is turned on; otherwise problems occur if we we started while the debugger was active (bug #1530345) */ event_add( tstates, event_type_null ); ui_menu_activate( UI_MENU_ITEM_MACHINE_PROFILER, 1 ); }
static BOOL win32ui_make_menu( void ) { /* Start various menus in the 'off' state */ ui_menu_activate( UI_MENU_ITEM_AY_LOGGING, 0 ); ui_menu_activate( UI_MENU_ITEM_FILE_MOVIE_RECORDING, 0 ); ui_menu_activate( UI_MENU_ITEM_MACHINE_PROFILER, 0 ); ui_menu_activate( UI_MENU_ITEM_RECORDING, 0 ); ui_menu_activate( UI_MENU_ITEM_RECORDING_ROLLBACK, 0 ); ui_menu_activate( UI_MENU_ITEM_TAPE_RECORDING, 0 ); #ifdef HAVE_LIB_XML2 ui_menu_activate( UI_MENU_ITEM_FILE_SVG_CAPTURE, 0 ); #endif return FALSE; }
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 void scld_from_snapshot( libspectrum_snap *snap ) { size_t i; int capabilities = machine_current->capabilities; if( capabilities & ( LIBSPECTRUM_MACHINE_CAPABILITY_TIMEX_MEMORY | LIBSPECTRUM_MACHINE_CAPABILITY_SE_MEMORY ) ) scld_hsr_write( 0x00f4, libspectrum_snap_out_scld_hsr( snap ) ); if( capabilities & LIBSPECTRUM_MACHINE_CAPABILITY_TIMEX_VIDEO ) scld_dec_write( 0x00ff, libspectrum_snap_out_scld_dec( snap ) ); if( libspectrum_snap_dock_active( snap ) ) { dck_active = 1; for( i = 0; i < 8; i++ ) { if( libspectrum_snap_dock_cart( snap, i ) ) scld_dock_exrom_from_snapshot( timex_dock, i, libspectrum_snap_dock_ram( snap, i ), libspectrum_snap_dock_cart( snap, i ) ); if( libspectrum_snap_exrom_cart( snap, i ) ) scld_dock_exrom_from_snapshot( timex_exrom, i, libspectrum_snap_exrom_ram( snap, i ), libspectrum_snap_exrom_cart( snap, i ) ); } if( capabilities & LIBSPECTRUM_MACHINE_CAPABILITY_TIMEX_DOCK ) ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 1 ); machine_current->memory_map(); } }
int ide_insert( const char *filename, libspectrum_ide_channel *chn, libspectrum_ide_unit unit, int (*commit_fn)( libspectrum_ide_unit unit ), char **setting, ui_menu_item item ) { int error; /* Remove any currently inserted disk; abort if we want to keep the current disk */ if( *setting ) if( ide_eject( chn, unit, commit_fn, setting, item ) ) return 0; settings_set_string( setting, filename ); error = libspectrum_ide_insert( chn, unit, filename ); if( error ) return error; error = ui_menu_activate( item, 1 ); if( error ) return error; return 0; }
int tape_record_stop( void ) { libspectrum_tape_block* block; /* put last sample into the recording buffer */ rec_state.tape_buffer_used = write_rec_buffer( rec_state.tape_buffer, rec_state.tape_buffer_used, rec_state.last_level_count ); /* stop scheduling events and turn buffer into a block and pop into the current tape */ event_remove_type( record_event ); block = libspectrum_tape_block_alloc( LIBSPECTRUM_TAPE_BLOCK_RLE_PULSE ); libspectrum_tape_block_set_scale( block, rec_state.tstates_per_sample ); libspectrum_tape_block_set_data_length( block, rec_state.tape_buffer_used ); libspectrum_tape_block_set_data( block, rec_state.tape_buffer ); libspectrum_tape_append_block( tape, block ); rec_state.tape_buffer = NULL; rec_state.tape_buffer_size = 0; rec_state.tape_buffer_used = 0; tape_modified = 1; ui_tape_browser_update( UI_TAPE_BROWSER_NEW_BLOCK, block ); tape_recording = 0; /* Also want to reenable other tape actions */ ui_menu_activate( UI_MENU_ITEM_TAPE_RECORDING, 0 ); return 0; }
int dck_reset( void ) { utils_file file; size_t num_block = 0; libspectrum_dck *dck; int error; dck_active = 0; if( !settings_current.dck_file ) { ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 0 ); return 0; } dck = libspectrum_dck_alloc(); error = utils_read_file( settings_current.dck_file, &file ); if( error ) { libspectrum_dck_free( dck, 0 ); return error; } error = libspectrum_dck_read2( dck, file.buffer, file.length, settings_current.dck_file ); if( error ) { utils_close_file( &file ); libspectrum_dck_free( dck, 0 ); return error; } utils_close_file( &file ); while( dck->dck[num_block] != NULL ) { memory_page *page; int i; libspectrum_dck_bank dck_bank = dck->dck[num_block]->bank; if( dck_bank != LIBSPECTRUM_DCK_BANK_HOME && dck_bank != LIBSPECTRUM_DCK_BANK_DOCK && dck_bank != LIBSPECTRUM_DCK_BANK_EXROM ) { ui_error( UI_ERROR_INFO, "Sorry, bank ID %i is unsupported", dck->dck[num_block]->bank ); libspectrum_dck_free( dck, 0 ); return 1; } for( i = 0; i < 8; i++ ) { libspectrum_byte *data; int j; switch( dck->dck[num_block]->access[i] ) { case LIBSPECTRUM_DCK_PAGE_NULL: break; case LIBSPECTRUM_DCK_PAGE_ROM: data = memory_pool_allocate( 0x2000 ); memcpy( data, dck->dck[num_block]->pages[i], 0x2000 ); for( j = 0; j < MEMORY_PAGES_IN_8K; j++ ) { page = dck_get_memory_page( dck_bank, i * MEMORY_PAGES_IN_8K + j); page->offset = j * MEMORY_PAGE_SIZE; page->writable = 0; page->save_to_snapshot = 1; page->page = data + page->offset; } break; case LIBSPECTRUM_DCK_PAGE_RAM_EMPTY: case LIBSPECTRUM_DCK_PAGE_RAM: /* Because the scr and snapshot code depends on the standard memory map being in the RAM[] array, we just copy RAM blocks from the HOME bank into the appropriate page; in other cases, we allocate ourselves a new page to store the contents in */ if( dck_bank == LIBSPECTRUM_DCK_BANK_HOME && i>1 ) { for( j = 0; j < MEMORY_PAGES_IN_8K; j++ ) { page = dck_get_memory_page( dck_bank, i * MEMORY_PAGES_IN_8K + j); if( dck->dck[num_block]->access[i] == LIBSPECTRUM_DCK_PAGE_RAM ) { memcpy( page->page, dck->dck[num_block]->pages[i] + j * MEMORY_PAGE_SIZE, MEMORY_PAGE_SIZE ); } else { memset( page->page, 0, MEMORY_PAGE_SIZE ); } } } else { data = memory_pool_allocate( 0x2000 ); if( dck->dck[num_block]->access[i] == LIBSPECTRUM_DCK_PAGE_RAM ) { memcpy( data, dck->dck[num_block]->pages[i], 0x2000 ); } else { memset( data, 0, 0x2000 ); } for( j = 0; j < MEMORY_PAGES_IN_8K; j++ ) { page = dck_get_memory_page( dck_bank, i * MEMORY_PAGES_IN_8K + j); page->offset = j * MEMORY_PAGE_SIZE; page->writable = 1; page->save_to_snapshot = 1; page->page = data + page->offset; } } break; } } num_block++; } dck_active = 1; /* Reset contention for pages */ scld_set_exrom_dock_contention(); /* Make the menu item to eject the cartridge active */ ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 1 ); return libspectrum_dck_free( dck, 0 ); }
int dck_reset( void ) { utils_file file; size_t num_block = 0; libspectrum_dck *dck; int error; dck_active = 0; if( !settings_current.dck_file ) { ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 0 ); return 0; } dck = libspectrum_dck_alloc(); error = utils_read_file( settings_current.dck_file, &file ); if( error ) { libspectrum_dck_free( dck, 0 ); return error; } error = libspectrum_dck_read2( dck, file.buffer, file.length, settings_current.dck_file ); if( error ) { utils_close_file( &file ); libspectrum_dck_free( dck, 0 ); return error; } if( utils_close_file( &file ) ) { libspectrum_dck_free( dck, 0 ); return 1; } while( dck->dck[num_block] != NULL ) { memory_page **mem; int i; switch( dck->dck[num_block]->bank ) { case LIBSPECTRUM_DCK_BANK_HOME: mem = memory_map_home; break; case LIBSPECTRUM_DCK_BANK_DOCK: mem = memory_map_dock; break; case LIBSPECTRUM_DCK_BANK_EXROM: mem = memory_map_exrom; break; default: ui_error( UI_ERROR_INFO, "Sorry, bank ID %i is unsupported", dck->dck[num_block]->bank ); libspectrum_dck_free( dck, 0 ); return 1; } for( i = 0; i < 8; i++ ) { switch( dck->dck[num_block]->access[i] ) { case LIBSPECTRUM_DCK_PAGE_NULL: break; case LIBSPECTRUM_DCK_PAGE_ROM: mem[i]->page = memory_pool_allocate( MEMORY_PAGE_SIZE ); if( !mem[i]->page ) return 1; memcpy( mem[i]->page, dck->dck[num_block]->pages[i], MEMORY_PAGE_SIZE ); mem[i]->writable = 0; mem[i]->source = MEMORY_SOURCE_CARTRIDGE; break; case LIBSPECTRUM_DCK_PAGE_RAM_EMPTY: case LIBSPECTRUM_DCK_PAGE_RAM: /* Because the scr and snapshot code depends on the standard memory map being in the RAM[] array, we just copy RAM blocks from the HOME bank into the appropriate page; in other cases, we allocate ourselves a new page to store the contents in */ if( !(dck->dck[num_block]->bank == LIBSPECTRUM_DCK_BANK_HOME && i>1) ) { mem[i]->page = memory_pool_allocate( MEMORY_PAGE_SIZE ); if( !mem[i]->page ) return 1; mem[i]->writable = 1; } mem[i]->source = MEMORY_SOURCE_CARTRIDGE; memcpy( mem[i]->page, dck->dck[num_block]->pages[i], MEMORY_PAGE_SIZE ); break; } } num_block++; } dck_active = 1; /* Make the menu item to eject the cartridge active */ ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 1 ); return libspectrum_dck_free( dck, 0 ); }