int machine_load_rom_bank_from_buffer( memory_page* bank_map, size_t which, int page_num, unsigned char *buffer, size_t length, int custom ) { size_t i, offset; bank_map[ which ].offset = 0; bank_map[ which ].page_num = page_num; bank_map[ which ].page = memory_pool_allocate( length ); if( !bank_map[ which ].page ) { ui_error( UI_ERROR_ERROR, "Out of memory at %s:%d", __FILE__, __LINE__ ); return 1; } memcpy( bank_map[ which ].page, buffer, length ); bank_map[ which ].source = custom ? MEMORY_SOURCE_CUSTOMROM : MEMORY_SOURCE_SYSTEM; for( i = 1, offset = MEMORY_PAGE_SIZE; offset < length; i++, offset += MEMORY_PAGE_SIZE ) { bank_map[ which + i ].offset = offset; bank_map[ which + i ].page_num = page_num; bank_map[ which + i ].page = bank_map[ which ].page + offset; bank_map[ which + i ].source = custom ? MEMORY_SOURCE_CUSTOMROM : MEMORY_SOURCE_SYSTEM; } return 0; }
bool game_buffer_editor_add_mpk_job(game_buffer *game_buffer, game_buffer_editor_job **ptr_to_new_job) { game_buffer_editor_job *job = (game_buffer_editor_job *)memory_pool_allocate(&game_buffer->editor->job_memory_pool); if (!job) { return false; } *job = {}; static uint64 job_id_counter = 0; job->id = job_id_counter; job_id_counter += 1; job->status = game_buffer_editor_job_progress; job->type = game_buffer_editor_job_mpk_import_type; sllist_push(&game_buffer->editor->job_list, job); *ptr_to_new_job = job; return true; }
static void scld_dock_exrom_from_snapshot( memory_page *dest, int page_num, int writable, void *source ) { int i; libspectrum_byte *data = memory_pool_allocate( 0x2000 ); memcpy( data, source, 0x2000 ); for( i = 0; i < MEMORY_PAGES_IN_8K; i++ ) { memory_page *page = &dest[ page_num * MEMORY_PAGES_IN_8K + i ]; page->offset = i * MEMORY_PAGE_SIZE; page->page_num = page_num; page->writable = writable; page->page = data + page->offset; page->save_to_snapshot = 1; } /* Reset contention for pages */ scld_set_exrom_dock_contention(); }
int machine_load_rom_bank_from_buffer( memory_page* bank_map, int page_num, unsigned char *buffer, size_t length, int custom ) { size_t offset; libspectrum_byte *data = memory_pool_allocate( length ); memory_page *page; memcpy( data, buffer, length ); for( page = &bank_map[ page_num * MEMORY_PAGES_IN_16K ], offset = 0; offset < length; page++, offset += MEMORY_PAGE_SIZE ) { page->offset = offset; page->page_num = page_num; page->page = data + offset; page->writable = 0; page->save_to_snapshot = custom; } return 0; }
bool game_buffer_editor_handle_mpk_import_message(game_buffer *game_buffer, mpk_import_named_pipe_message *message) { game_buffer_editor_job *job = game_buffer->editor->job_list; while (job->id != message->job_id) { job = job->next; } assert(job->type == game_buffer_editor_job_mpk_import_type); switch (message->type) { case mpk_import_named_pipe_message_type_error : { job->status = game_buffer_editor_job_error; } break; case mpk_import_named_pipe_message_type_no_space : { job->status = game_buffer_editor_job_warning; } break; case mpk_import_named_pipe_message_type_progress : { job->status = game_buffer_editor_job_progress; } break; case mpk_import_named_pipe_message_type_done : { job->status = game_buffer_editor_job_done; } break; } if (message->msg[0] != '\0') { game_buffer_editor_job_message *new_job_message = (game_buffer_editor_job_message *)memory_pool_allocate(&game_buffer->editor->job_message_memory_pool); assert(new_job_message); m_array_assign(new_job_message->buf, message->msg); sllist_append(&job->mpk_import.message_list, new_job_message); } return true; }
void mpk_import_add_named_pipe_instance(common_vars *common_vars) { HANDLE named_pipe_handle = CreateNamedPipeA("\\\\.\\pipe\\" m_mpk_import_named_pipe_name, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE, PIPE_UNLIMITED_INSTANCES, 4096, 4096, 0, nullptr); if (!named_pipe_handle) { m_last_error_str(err); m_die("cannot create mpk import named pipe instance, call to \"CreateNamedPipeA\" failed\nerr: %s", err); } HANDLE io_completion_port = CreateIoCompletionPort(named_pipe_handle, common_vars->io_completion_port, mpk_import_named_pipe_event, 0); if (!io_completion_port) { m_last_error_str(err_str); m_die("cannot connect mpk import named pipe to io completion port, call to \"CreateIoCompletionPort\" failed\nerr: %s", err_str); } mpk_import_named_pipe_instance *new_named_pipe_instance = (mpk_import_named_pipe_instance *)memory_pool_allocate(&common_vars->mpk_import_named_pipe_instance_memory_pool); *new_named_pipe_instance = {}; new_named_pipe_instance->handle = named_pipe_handle; sllist_push(&common_vars->mpk_import_named_pipe_instance_list, new_named_pipe_instance); ConnectNamedPipe(named_pipe_handle, &new_named_pipe_instance->overlapped); }
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 ); }