static int dtlbasic_read_snapshot(struct snapshot_s *s) { BYTE major_version, minor_version; snapshot_module_t *m; /* enable device */ set_dtlbasic_dongle_enabled(1, NULL); m = snapshot_module_open(s, snap_module_name, &major_version, &minor_version); if (m == NULL) { return -1; } /* Do not accept versions higher than current */ if (major_version > SNAP_MAJOR || minor_version > SNAP_MINOR) { snapshot_set_error(SNAPSHOT_MODULE_HIGHER_VERSION); goto fail; } if (0 || SMR_DW_INT(m, &dtlbasic_counter) < 0 || SMR_DW_INT(m, &write_status) < 0 || SMR_DW_INT(m, &sense_status) < 0 || SMR_DW_INT(m, &dtlbasic_state) < 0) { goto fail; } return snapshot_module_close(m); fail: snapshot_module_close(m); return -1; }
int actionreplay2_snapshot_read_module(snapshot_t *s) { BYTE vmajor, vminor; snapshot_module_t *m; m = snapshot_module_open(s, SNAP_MODULE_NAME, &vmajor, &vminor); if (m == NULL) { return -1; } if ((vmajor != CART_DUMP_VER_MAJOR) || (vminor != CART_DUMP_VER_MINOR)) { snapshot_module_close(m); return -1; } if (0 || (SMR_B_INT(m, &ar_enabled) < 0) || (SMR_DW_INT(m, &ar_cap_enable) < 0) || (SMR_DW_INT(m, &ar_cap_disable) < 0) || (SMR_BA(m, roml_banks, 0x4000) < 0)) { snapshot_module_close(m); return -1; } snapshot_module_close(m); return actionreplay2_common_attach(); }
int interrupt_read_new_snapshot(interrupt_cpu_status_t *cs, snapshot_module_t *m) { if (SMR_DW_INT(m, &cs->nirq) < 0 || SMR_DW_INT(m, &cs->nnmi) < 0 || SMR_DW_UINT(m, &cs->global_pending_int) < 0) { return -1; } return 0; }
static int paperclip64_read_snapshot(struct snapshot_s *s, int port) { BYTE major_version, minor_version; snapshot_module_t *m; m = snapshot_module_open(s, snap_module_name, &major_version, &minor_version); if (m == NULL) { return -1; } /* Do not accept versions higher than current */ if (major_version > SNAP_MAJOR || minor_version > SNAP_MINOR) { snapshot_set_error(SNAPSHOT_MODULE_HIGHER_VERSION); goto fail; } if (0 || SMR_DW_INT(m, &counter) < 0 || SMR_B(m, &command) < 0 || SMR_B_INT(m, &state) < 0) { goto fail; } return snapshot_module_close(m); fail: snapshot_module_close(m); return -1; }
int ds12c887rtc_snapshot_read_module(snapshot_t *s) { BYTE vmajor, vminor; snapshot_module_t *m; int temp_ds12c887rtc_address; m = snapshot_module_open(s, SNAP_MODULE_NAME, &vmajor, &vminor); if (m == NULL) { return -1; } if ((vmajor != CART_DUMP_VER_MAJOR) || (vminor != CART_DUMP_VER_MINOR)) { snapshot_module_close(m); return -1; } /* FIXME: Implement the RTC snapshot part */ if (0 || (SMR_DW_INT(m, &temp_ds12c887rtc_address) < 0)) { snapshot_module_close(m); return -1; } snapshot_module_close(m); /* HACK set address to an invalid value, then use the function */ ds12c887rtc_base_address = -1; set_ds12c887rtc_base(temp_ds12c887rtc_address, NULL); return ds12c887rtc_enable(); }
int digimax_snapshot_read_module(snapshot_t *s) { BYTE vmajor, vminor; snapshot_module_t *m; int temp_digimax_address; m = snapshot_module_open(s, SNAP_MODULE_NAME, &vmajor, &vminor); if (m == NULL) { return -1; } if ((vmajor != CART_DUMP_VER_MAJOR) || (vminor != CART_DUMP_VER_MINOR)) { snapshot_module_close(m); return -1; } if (0 || (SMR_DW_INT(m, &temp_digimax_address) < 0) /* FIXME: Implement the userport part in userport_digimax.c */ #if 0 || (SMR_B(m, &digimax_userport_address) < 0) || (SMR_B(m, &digimax_userport_direction_A) < 0) || (SMR_B(m, &digimax_userport_direction_B) < 0) #endif || (SMR_BA(m, digimax_sound_data, 4) < 0) || (SMR_B(m, &snd.voice0) < 0) || (SMR_B(m, &snd.voice1) < 0) || (SMR_B(m, &snd.voice2) < 0) || (SMR_B(m, &snd.voice3) < 0)) { snapshot_module_close(m); return -1; } snapshot_module_close(m); /* HACK set address to an invalid value, then use the function */ digimax_address = -1; set_digimax_base(temp_digimax_address, NULL); return digimax_enable(); }
int vic_snapshot_read_module(snapshot_t *s) { WORD i; snapshot_module_t *m; BYTE major_version, minor_version; WORD w; BYTE b; sound_close(); m = snapshot_module_open(s, snap_module_name, &major_version, &minor_version); if (m == NULL) { return -1; } if (major_version > SNAP_MAJOR || minor_version > SNAP_MINOR) { log_error(vic.log, "Snapshot module version (%d.%d) newer than %d.%d.", major_version, minor_version, SNAP_MAJOR, SNAP_MINOR); goto fail; } if (SMR_B(m, &b) < 0) { goto fail; } if (b != VIC_RASTER_CYCLE(maincpu_clk)) { log_error(vic.log, "Cycle value (%d) incorrect; should be %d.", (int)b, VIC_RASTER_CYCLE(maincpu_clk)); goto fail; } vic.raster_cycle = (unsigned int)b; if (SMR_W(m, &w) < 0) { goto fail; } if (w != VIC_RASTER_Y(maincpu_clk)) { log_error(vic.log, "Raster line value (%d) incorrect; should be %d.", (int)w, VIC_RASTER_Y(maincpu_clk)); goto fail; } if (SMR_W(m, &w) < 0) { goto fail; } vic.area = (vic_area_state_t)w; if (SMR_W(m, &w) < 0) { goto fail; } vic.fetch_state = (vic_fetch_state_t)w; if (0 || (SMR_DW_UINT(m, &vic.raster_line) < 0) || (SMR_DW_UINT(m, &vic.text_cols) < 0) || (SMR_DW_UINT(m, &vic.text_lines) < 0) || (SMR_DW_UINT(m, &vic.pending_text_cols) < 0) || (SMR_DW_UINT(m, &vic.line_was_blank) < 0) || (SMR_DW_UINT(m, &vic.memptr) < 0) || (SMR_DW_UINT(m, &vic.memptr_inc) < 0) || (SMR_DW_UINT(m, &vic.row_counter) < 0) || (SMR_DW_UINT(m, &vic.buf_offset) < 0) || SMR_B_INT(m, &vic.light_pen.state) < 0 || SMR_B_INT(m, &vic.light_pen.triggered) < 0 || SMR_DW_INT(m, &vic.light_pen.x) < 0 || SMR_DW_INT(m, &vic.light_pen.y) < 0 || SMR_DW_INT(m, &vic.light_pen.x_extra_bits) < 0 || SMR_DW(m, &vic.light_pen.trigger_cycle) < 0 || (SMR_B(m, &vic.vbuf) < 0)) { goto fail; } /* Color RAM. */ if (SMR_BA(m, mem_ram + 0x9400, 0x400) < 0) { goto fail; } for (i = 0; i < 0x10; i++) { if (SMR_B(m, &b) < 0) { goto fail; } /* XXX: This assumes that there are no side effects. */ vic_store(i, b); } raster_force_repaint(&vic.raster); return snapshot_module_close(m); fail: if (m != NULL) snapshot_module_close(m); return -1; }
int sfx_soundexpander_snapshot_read_module(snapshot_t *s) { BYTE vmajor, vminor; snapshot_module_t *m; int temp_chip; FM_OPL *chip = NULL; int temp_connect1; int x, y; m = snapshot_module_open(s, SNAP_MODULE_NAME, &vmajor, &vminor); if (m == NULL) { return -1; } if ((vmajor != CART_DUMP_VER_MAJOR) || (vminor != CART_DUMP_VER_MINOR)) { snapshot_module_close(m); return -1; } if (0 || (SMR_DW_INT(m, &temp_chip) < 0)) { snapshot_module_close(m); return -1; } if (sfx_soundexpander_sound_chip.chip_enabled) { set_sfx_soundexpander_enabled(0, NULL); } set_sfx_soundexpander_chip(temp_chip, NULL); set_sfx_soundexpander_enabled(1, NULL); chip = (temp_chip == 3526) ? YM3526_chip : YM3812_chip; if (0 || (SMR_B(m, &snd.command) < 0)) { snapshot_module_close(m); return -1; } for (x = 0; x < 9; x++) { for (y = 0; y < 2; y++) { if (0 || (SMR_DW_UINT(m, &chip->P_CH[x].SLOT[y].ar) < 0) || (SMR_DW_UINT(m, &chip->P_CH[x].SLOT[y].dr) < 0) || (SMR_DW_UINT(m, &chip->P_CH[x].SLOT[y].rr) < 0) || (SMR_B(m, &chip->P_CH[x].SLOT[y].KSR) < 0) || (SMR_B(m, &chip->P_CH[x].SLOT[y].ksl) < 0) || (SMR_B(m, &chip->P_CH[x].SLOT[y].ksr) < 0) || (SMR_B(m, &chip->P_CH[x].SLOT[y].mul) < 0) || (SMR_DW_UINT(m, &chip->P_CH[x].SLOT[y].Cnt) < 0) || (SMR_DW_UINT(m, &chip->P_CH[x].SLOT[y].Incr) < 0) || (SMR_B(m, &chip->P_CH[x].SLOT[y].FB) < 0) || (SMR_DW_INT(m, &temp_connect1) < 0) || (SMR_DW_INT(m, &chip->P_CH[x].SLOT[y].op1_out[0]) < 0) || (SMR_DW_INT(m, &chip->P_CH[x].SLOT[y].op1_out[1]) < 0) || (SMR_B(m, &chip->P_CH[x].SLOT[y].CON) < 0) || (SMR_B(m, &chip->P_CH[x].SLOT[y].eg_type) < 0) || (SMR_B(m, &chip->P_CH[x].SLOT[y].state) < 0) || (SMR_DW_UINT(m, &chip->P_CH[x].SLOT[y].TL) < 0) || (SMR_DW_INT(m, &chip->P_CH[x].SLOT[y].TLL) < 0) || (SMR_DW_INT(m, &chip->P_CH[x].SLOT[y].volume) < 0) || (SMR_DW_UINT(m, &chip->P_CH[x].SLOT[y].sl) < 0) || (SMR_B(m, &chip->P_CH[x].SLOT[y].eg_sh_ar) < 0) || (SMR_B(m, &chip->P_CH[x].SLOT[y].eg_sel_ar) < 0) || (SMR_B(m, &chip->P_CH[x].SLOT[y].eg_sh_dr) < 0) || (SMR_B(m, &chip->P_CH[x].SLOT[y].eg_sel_dr) < 0) || (SMR_B(m, &chip->P_CH[x].SLOT[y].eg_sh_rr) < 0) || (SMR_B(m, &chip->P_CH[x].SLOT[y].eg_sel_rr) < 0) || (SMR_DW_UINT(m, &chip->P_CH[x].SLOT[y].key) < 0) || (SMR_DW_UINT(m, &chip->P_CH[x].SLOT[y].AMmask) < 0) || (SMR_B(m, &chip->P_CH[x].SLOT[y].vib) < 0) || (SMR_W(m, &chip->P_CH[x].SLOT[y].wavetable) < 0)) { snapshot_module_close(m); return -1; } set_connect1(chip->P_CH[x].SLOT[y].connect1, temp_connect1); } if (0 || (SMR_DW_UINT(m, &chip->P_CH[x].block_fnum) < 0) || (SMR_DW_UINT(m, &chip->P_CH[x].fc) < 0) || (SMR_DW_UINT(m, &chip->P_CH[x].ksl_base) < 0) || (SMR_B(m, &chip->P_CH[x].kcode) < 0)) { snapshot_module_close(m); return -1; } } if (0 || (SMR_DW_UINT(m, &chip->eg_cnt) < 0) || (SMR_DW_UINT(m, &chip->eg_timer) < 0) || (SMR_DW_UINT(m, &chip->eg_timer_add) < 0) || (SMR_DW_UINT(m, &chip->eg_timer_overflow) < 0) || (SMR_B(m, &chip->rhythm) < 0)) { snapshot_module_close(m); return -1; } for (x = 0; x < 1024; x++) { if (0 || (SMR_DW_UINT(m, &chip->fn_tab[x]) < 0)) { snapshot_module_close(m); return -1; } } if (0 || (SMR_B(m, &chip->lfo_am_depth) < 0) || (SMR_B(m, &chip->lfo_pm_depth_range) < 0) || (SMR_DW_UINT(m, &chip->lfo_am_cnt) < 0) || (SMR_DW_UINT(m, &chip->lfo_am_inc) < 0) || (SMR_DW_UINT(m, &chip->lfo_pm_cnt) < 0) || (SMR_DW_UINT(m, &chip->lfo_pm_inc) < 0) || (SMR_DW_UINT(m, &chip->noise_rng) < 0) || (SMR_DW_UINT(m, &chip->noise_p) < 0) || (SMR_DW_UINT(m, &chip->noise_f) < 0) || (SMR_B(m, &chip->wavesel) < 0) || (SMR_DW_UINT(m, &chip->T[0]) < 0) || (SMR_DW_UINT(m, &chip->T[1]) < 0) || (SMR_B(m, &chip->st[0]) < 0) || (SMR_B(m, &chip->st[1]) < 0) || (SMR_B(m, &chip->type) < 0) || (SMR_B(m, &chip->address) < 0) || (SMR_B(m, &chip->status) < 0) || (SMR_B(m, &chip->statusmask) < 0) || (SMR_B(m, &chip->mode) < 0) || (SMR_DW_UINT(m, &chip->clock) < 0) || (SMR_DW_UINT(m, &chip->rate) < 0) || (SMR_DB(m, &chip->freqbase) < 0)) { snapshot_module_close(m); return -1; } snapshot_module_close(m); return 0; }
int vic20cart_snapshot_read_module(snapshot_t *s) { BYTE vmajor, vminor; snapshot_module_t *m; int new_cart_type, cartridge_reset; int ret = 0; m = snapshot_module_open(s, SNAP_MODULE_NAME, &vmajor, &vminor); if (m == NULL) { return -1; } if (vmajor != VIC20CART_DUMP_VER_MAJOR) { snapshot_module_close(m); return -1; } if (SMR_DW_INT(m, &new_cart_type) < 0) { snapshot_module_close(m); return -1; } snapshot_module_close(m); /* disable cartridge reset while detaching old cart */ resources_get_int("CartridgeReset", &cartridge_reset); resources_set_int("CartridgeReset", 0); cartridge_detach_image(-1); resources_set_int("CartridgeReset", cartridge_reset); /* disallow "set as default" and write back */ cartridge_is_from_snapshot = 1; vic20cart_type = new_cart_type; mem_cartridge_type = new_cart_type; switch (vic20cart_type) { case CARTRIDGE_VIC20_GENERIC: ret = generic_snapshot_read_module(s); break; case CARTRIDGE_VIC20_FP: ret = vic_fp_snapshot_read_module(s); break; case CARTRIDGE_VIC20_MEGACART: ret = megacart_snapshot_read_module(s); break; case CARTRIDGE_VIC20_FINAL_EXPANSION: ret = finalexpansion_snapshot_read_module(s); break; case CARTRIDGE_NONE: /* cart already detached, nothing to do */ break; default: /* unknown cart */ ret = -1; break; } if (ret < 0) { vic20cart_type = CARTRIDGE_NONE; mem_cartridge_type = CARTRIDGE_NONE; } return ret; }
int drive_snapshot_read_module(snapshot_t *s) { BYTE major_version, minor_version; int i; snapshot_module_t *m; char snap_module_name[] = "DRIVE"; DWORD rotation_table_ptr[DRIVE_NUM]; CLOCK attach_clk[DRIVE_NUM]; CLOCK detach_clk[DRIVE_NUM]; CLOCK attach_detach_clk[DRIVE_NUM]; int drive_true_emulation; int sync_factor; drive_t *drive; int dummy; int half_track[DRIVE_NUM]; m = snapshot_module_open(s, snap_module_name, &major_version, &minor_version); if (m == NULL) { /* If this module is not found true emulation is off. */ resources_set_int("DriveTrueEmulation", 0); return 0; } drive_gcr_data_writeback_all(); if (major_version > DRIVE_SNAP_MAJOR || minor_version > DRIVE_SNAP_MINOR) { log_error(drive_snapshot_log, "Snapshot module version (%d.%d) newer than %d.%d.", major_version, minor_version, DRIVE_SNAP_MAJOR, DRIVE_SNAP_MINOR); } /* If this module exists true emulation is enabled. */ /* XXX drive_true_emulation = 1 */ resources_set_int("DriveTrueEmulation", 1); if (SMR_DW_INT(m, &sync_factor) < 0) { snapshot_module_close(m); return -1; } /* TODO: NUM_DRIVES drives instead of 2 */ for (i = 0; i < 2; i++) { drive = drive_context[i]->drive; /* Partially read 1.0 snapshots */ if (major_version == 1 && minor_version == 0) { if (0 || SMR_DW_UL(m, &(drive->snap_accum)) < 0 || SMR_DW(m, &(attach_clk[i])) < 0 || SMR_DW_INT(m, &dummy) < 0 || SMR_B_INT(m, (int *)&(drive->byte_ready_level)) < 0 || SMR_B_INT(m, &(drive->clock_frequency)) < 0 || SMR_W_INT(m, &half_track[i]) < 0 || SMR_DW(m, &(detach_clk[i])) < 0 || SMR_B(m, (BYTE *)&dummy) < 0 || SMR_B(m, (BYTE *)&dummy) < 0 || SMR_B_INT(m, &(drive->extend_image_policy)) < 0 || SMR_B_INT(m, &dummy) < 0 || SMR_DW_UINT(m, &(drive->GCR_head_offset)) < 0 || SMR_B(m, &(drive->GCR_read)) < 0 || SMR_B(m, &(drive->GCR_write_value)) < 0 || SMR_B_INT(m, &(drive->idling_method)) < 0 || SMR_B_INT(m, &dummy) < 0 || SMR_B_INT(m, &(drive->parallel_cable)) < 0 || SMR_B_INT(m, &(drive->read_only)) < 0 || SMR_DW(m, &(drive->snap_rotation_last_clk)) < 0 || SMR_DW(m, &rotation_table_ptr[i]) < 0 || SMR_DW_UINT(m, &(drive->type)) < 0 ) { snapshot_module_close(m); return -1; } /* Partially read 1.1 snapshots */ } else if (major_version == 1 && minor_version == 1) { if (0 || SMR_DW(m, &(attach_clk[i])) < 0 || SMR_B_INT(m, (int *)&(drive->byte_ready_level)) < 0 || SMR_B_INT(m, &(drive->clock_frequency)) < 0 || SMR_W_INT(m, &half_track[i]) < 0 || SMR_DW(m, &(detach_clk[i])) < 0 || SMR_B(m, (BYTE *)&dummy) < 0 || SMR_B(m, (BYTE *)&dummy) < 0 || SMR_B_INT(m, &(drive->extend_image_policy)) < 0 || SMR_DW_UINT(m, &(drive->GCR_head_offset)) < 0 || SMR_B(m, &(drive->GCR_read)) < 0 || SMR_B(m, &(drive->GCR_write_value)) < 0 || SMR_B_INT(m, &(drive->idling_method)) < 0 || SMR_B_INT(m, &(drive->parallel_cable)) < 0 || SMR_B_INT(m, &(drive->read_only)) < 0 || SMR_DW(m, &rotation_table_ptr[i]) < 0 || SMR_DW_UINT(m, &(drive->type)) < 0 || SMR_DW_UL(m, &(drive->snap_accum)) < 0 || SMR_DW(m, &(drive->snap_rotation_last_clk)) < 0 || SMR_DW_INT(m, &(drive->snap_bit_counter)) < 0 || SMR_DW_INT(m, &(drive->snap_zero_count)) < 0 || SMR_W_INT(m, &(drive->snap_last_read_data)) < 0 || SMR_B(m, &(drive->snap_last_write_data)) < 0 || SMR_DW_INT(m, &(drive->snap_seed)) < 0 ) { snapshot_module_close(m); return -1; } /* Partially read 1.2 snapshots */ } else if (major_version == 1 && minor_version == 2) { if (0 || SMR_DW(m, &(attach_clk[i])) < 0 || SMR_B_INT(m, (int *)&(drive->byte_ready_level)) < 0 || SMR_B_INT(m, &(drive->clock_frequency)) < 0 || SMR_W_INT(m, &half_track[i]) < 0 || SMR_DW(m, &(detach_clk[i])) < 0 || SMR_B(m, (BYTE *)&dummy) < 0 || SMR_B(m, (BYTE *)&dummy) < 0 || SMR_B_INT(m, &(drive->extend_image_policy)) < 0 || SMR_DW_UINT(m, &(drive->GCR_head_offset)) < 0 || SMR_B(m, &(drive->GCR_read)) < 0 || SMR_B(m, &(drive->GCR_write_value)) < 0 || SMR_B_INT(m, &(drive->idling_method)) < 0 || SMR_B_INT(m, &(drive->parallel_cable)) < 0 || SMR_B_INT(m, &(drive->read_only)) < 0 || SMR_DW(m, &rotation_table_ptr[i]) < 0 || SMR_DW_UINT(m, &(drive->type)) < 0 || SMR_DW_UL(m, &(drive->snap_accum)) < 0 || SMR_DW(m, &(drive->snap_rotation_last_clk)) < 0 || SMR_DW_INT(m, &(drive->snap_bit_counter)) < 0 || SMR_DW_INT(m, &(drive->snap_zero_count)) < 0 || SMR_W_INT(m, &(drive->snap_last_read_data)) < 0 || SMR_B(m, &(drive->snap_last_write_data)) < 0 || SMR_DW_INT(m, &(drive->snap_seed)) < 0 || SMR_DW(m, &(drive->snap_speed_zone)) < 0 || SMR_DW(m, &(drive->snap_ue7_dcba)) < 0 || SMR_DW(m, &(drive->snap_ue7_counter)) < 0 || SMR_DW(m, &(drive->snap_uf4_counter)) < 0 || SMR_DW(m, &(drive->snap_fr_randcount)) < 0 || SMR_DW(m, &(drive->snap_filter_counter)) < 0 || SMR_DW(m, &(drive->snap_filter_state)) < 0 || SMR_DW(m, &(drive->snap_filter_last_state)) < 0 || SMR_DW(m, &(drive->snap_write_flux)) < 0 || SMR_DW(m, &(drive->snap_PulseHeadPosition)) < 0 || SMR_DW(m, &(drive->snap_xorShift32)) < 0 ) { snapshot_module_close(m); return -1; } } else if (major_version == 1 && minor_version == 3) { if (0 || SMR_DW(m, &(attach_clk[i])) < 0 || SMR_B_INT(m, (int *)&(drive->byte_ready_level)) < 0 || SMR_B_INT(m, &(drive->clock_frequency)) < 0 || SMR_W_INT(m, &half_track[i]) < 0 || SMR_DW(m, &(detach_clk[i])) < 0 || SMR_B(m, (BYTE *)&dummy) < 0 || SMR_B(m, (BYTE *)&dummy) < 0 || SMR_B_INT(m, &(drive->extend_image_policy)) < 0 || SMR_DW_UINT(m, &(drive->GCR_head_offset)) < 0 || SMR_B(m, &(drive->GCR_read)) < 0 || SMR_B(m, &(drive->GCR_write_value)) < 0 || SMR_B_INT(m, &(drive->idling_method)) < 0 || SMR_B_INT(m, &(drive->parallel_cable)) < 0 || SMR_B_INT(m, &(drive->read_only)) < 0 || SMR_DW(m, &rotation_table_ptr[i]) < 0 || SMR_DW_UINT(m, &(drive->type)) < 0 || SMR_DW_UL(m, &(drive->snap_accum)) < 0 || SMR_DW(m, &(drive->snap_rotation_last_clk)) < 0 || SMR_DW_INT(m, &(drive->snap_bit_counter)) < 0 || SMR_DW_INT(m, &(drive->snap_zero_count)) < 0 || SMR_W_INT(m, &(drive->snap_last_read_data)) < 0 || SMR_B(m, &(drive->snap_last_write_data)) < 0 || SMR_DW_INT(m, &(drive->snap_seed)) < 0 || SMR_DW(m, &(drive->snap_speed_zone)) < 0 || SMR_DW(m, &(drive->snap_ue7_dcba)) < 0 || SMR_DW(m, &(drive->snap_ue7_counter)) < 0 || SMR_DW(m, &(drive->snap_uf4_counter)) < 0 || SMR_DW(m, &(drive->snap_fr_randcount)) < 0 || SMR_DW(m, &(drive->snap_filter_counter)) < 0 || SMR_DW(m, &(drive->snap_filter_state)) < 0 || SMR_DW(m, &(drive->snap_filter_last_state)) < 0 || SMR_DW(m, &(drive->snap_write_flux)) < 0 || SMR_DW(m, &(drive->snap_PulseHeadPosition)) < 0 || SMR_DW(m, &(drive->snap_xorShift32)) < 0 || SMR_DW(m, &(drive->snap_so_delay)) < 0 ) { snapshot_module_close(m); return -1; } } else { if (0 || SMR_DW(m, &(attach_clk[i])) < 0 || SMR_B_INT(m, (int *)&(drive->byte_ready_level)) < 0 || SMR_B_INT(m, &(drive->clock_frequency)) < 0 || SMR_W_INT(m, &half_track[i]) < 0 || SMR_DW(m, &(detach_clk[i])) < 0 || SMR_B(m, (BYTE *)&dummy) < 0 || SMR_B(m, (BYTE *)&dummy) < 0 || SMR_B_INT(m, &(drive->extend_image_policy)) < 0 || SMR_DW_UINT(m, &(drive->GCR_head_offset)) < 0 || SMR_B(m, &(drive->GCR_read)) < 0 || SMR_B(m, &(drive->GCR_write_value)) < 0 || SMR_B_INT(m, &(drive->idling_method)) < 0 || SMR_B_INT(m, &(drive->parallel_cable)) < 0 || SMR_B_INT(m, &(drive->read_only)) < 0 || SMR_DW(m, &rotation_table_ptr[i]) < 0 || SMR_DW_UINT(m, &(drive->type)) < 0 || SMR_DW_UL(m, &(drive->snap_accum)) < 0 || SMR_DW(m, &(drive->snap_rotation_last_clk)) < 0 || SMR_DW_INT(m, &(drive->snap_bit_counter)) < 0 || SMR_DW_INT(m, &(drive->snap_zero_count)) < 0 || SMR_W_INT(m, &(drive->snap_last_read_data)) < 0 || SMR_B(m, &(drive->snap_last_write_data)) < 0 || SMR_DW_INT(m, &(drive->snap_seed)) < 0 || SMR_DW(m, &(drive->snap_speed_zone)) < 0 || SMR_DW(m, &(drive->snap_ue7_dcba)) < 0 || SMR_DW(m, &(drive->snap_ue7_counter)) < 0 || SMR_DW(m, &(drive->snap_uf4_counter)) < 0 || SMR_DW(m, &(drive->snap_fr_randcount)) < 0 || SMR_DW(m, &(drive->snap_filter_counter)) < 0 || SMR_DW(m, &(drive->snap_filter_state)) < 0 || SMR_DW(m, &(drive->snap_filter_last_state)) < 0 || SMR_DW(m, &(drive->snap_write_flux)) < 0 || SMR_DW(m, &(drive->snap_PulseHeadPosition)) < 0 || SMR_DW(m, &(drive->snap_xorShift32)) < 0 || SMR_DW(m, &(drive->snap_so_delay)) < 0 || SMR_DW(m, &(drive->snap_cycle_index)) < 0 || SMR_DW(m, &(drive->snap_ref_advance)) < 0 || SMR_DW(m, &(drive->snap_req_ref_cycles)) < 0 ) { snapshot_module_close(m); return -1; } } } /* this one is new, so don't test so stay compatible with old snapshots */ for (i = 0; i < 2; i++) { drive = drive_context[i]->drive; SMR_DW(m, &(attach_detach_clk[i])); } /* these are even newer */ for (i = 0; i < 2; i++) { drive = drive_context[i]->drive; SMR_B_INT(m, (int *)&(drive->byte_ready_edge)); SMR_B_INT(m, (int *)&(drive->byte_ready_active)); } snapshot_module_close(m); m = NULL; rotation_table_set(rotation_table_ptr); drive = drive_context[0]->drive; switch (drive->type) { case DRIVE_TYPE_1540: case DRIVE_TYPE_1541: case DRIVE_TYPE_1541II: case DRIVE_TYPE_1551: case DRIVE_TYPE_1570: case DRIVE_TYPE_1571: case DRIVE_TYPE_1571CR: case DRIVE_TYPE_1581: case DRIVE_TYPE_2000: case DRIVE_TYPE_4000: case DRIVE_TYPE_2031: case DRIVE_TYPE_1001: case DRIVE_TYPE_2040: case DRIVE_TYPE_3040: case DRIVE_TYPE_4040: case DRIVE_TYPE_8050: case DRIVE_TYPE_8250: drive->enable = 1; machine_drive_rom_setup_image(0); drivemem_init(drive_context[0], drive->type); resources_set_int("Drive8IdleMethod", drive->idling_method); driverom_initialize_traps(drive); drive_set_active_led_color(drive->type, 0); machine_bus_status_drivetype_set(8, 1); break; case DRIVE_TYPE_NONE: drive_disable(drive_context[0]); machine_bus_status_drivetype_set(8, 0); break; default: return -1; } drive = drive_context[1]->drive; switch (drive->type) { case DRIVE_TYPE_1540: case DRIVE_TYPE_1541: case DRIVE_TYPE_1541II: case DRIVE_TYPE_1551: case DRIVE_TYPE_1570: case DRIVE_TYPE_1571: case DRIVE_TYPE_1581: case DRIVE_TYPE_2000: case DRIVE_TYPE_4000: case DRIVE_TYPE_2031: case DRIVE_TYPE_1001: /* drive 1 does not allow dual disk drive */ drive->enable = 1; machine_drive_rom_setup_image(1); drivemem_init(drive_context[1], drive->type); resources_set_int("Drive9IdleMethod", drive->idling_method); driverom_initialize_traps(drive); drive_set_active_led_color(drive->type, 1); machine_bus_status_drivetype_set(9, 1); break; case DRIVE_TYPE_NONE: case DRIVE_TYPE_8050: case DRIVE_TYPE_8250: drive_disable(drive_context[1]); machine_bus_status_drivetype_set(9, 0); break; default: return -1; } /* Clear parallel cable before undumping parallel port values. */ for (i = 0; i < DRIVE_PC_NUM; i++) { parallel_cable_drive_write(i, 0xff, PARALLEL_WRITE, 0); parallel_cable_drive_write(i, 0xff, PARALLEL_WRITE, 1); } for (i = 0; i < 2; i++) { drive = drive_context[i]->drive; if (drive->enable) { if (drive->type == DRIVE_TYPE_2000 || drive->type == DRIVE_TYPE_4000) { if (drivecpu65c02_snapshot_read_module(drive_context[i], s) < 0) { return -1; } } else { if (drivecpu_snapshot_read_module(drive_context[i], s) < 0) { return -1; } } if (machine_drive_snapshot_read(drive_context[i], s) < 0) { return -1; } } } if (drive_snapshot_read_image_module(s, 0) < 0 || drive_snapshot_read_gcrimage_module(s, 0) < 0 || drive_snapshot_read_p64image_module(s, 0) < 0) { return -1; } if (drive_snapshot_read_image_module(s, 1) < 0 || drive_snapshot_read_gcrimage_module(s, 1) < 0 || drive_snapshot_read_p64image_module(s, 1) < 0) { return -1; } if (driverom_snapshot_read(s, drive_context[0]->drive) < 0) { return -1; } if (driverom_snapshot_read(s, drive_context[1]->drive) < 0) { return -1; } for (i = 0; i < 2; i++) { drive = drive_context[i]->drive; if (drive->type != DRIVE_TYPE_NONE) { drive_enable(drive_context[i]); drive->attach_clk = attach_clk[i]; drive->detach_clk = detach_clk[i]; drive->attach_detach_clk = attach_detach_clk[i]; } } for (i = 0; i < 2; i++) { int side = 0; drive = drive_context[i]->drive; if (drive->type == DRIVE_TYPE_1570 || drive->type == DRIVE_TYPE_1571 || drive->type == DRIVE_TYPE_1571CR) { if (half_track[i] > (DRIVE_HALFTRACKS_1571 + 1)) { side = 1; half_track[i] -= DRIVE_HALFTRACKS_1571; } } drive_set_half_track(half_track[i], side, drive); resources_set_int("MachineVideoStandard", sync_factor); } /* stop currently active drive sounds (bug #3539422) * FIXME: when the drive sound emulation becomes more precise, we might * want/need to save a snapshot of its current state too */ drive_sound_stop(); iec_update_ports_embedded(); drive_update_ui_status(); resources_get_int("DriveTrueEmulation", &drive_true_emulation); if (vdrive_snapshot_module_read(s, drive_true_emulation ? 10 : 8) < 0) { return -1; } return 0; }
int ramcart_snapshot_read_module(snapshot_t *s) { uint8_t vmajor, vminor; snapshot_module_t *m; m = snapshot_module_open(s, snap_module_name, &vmajor, &vminor); if (m == NULL) { return -1; } /* Do not accept versions higher than current */ if (vmajor > SNAP_MAJOR || vminor > SNAP_MINOR) { snapshot_set_error(SNAPSHOT_MODULE_HIGHER_VERSION); goto fail; } if (0 || (SMR_B_INT(m, &ramcart_enabled) < 0) || (SMR_B_INT(m, &ramcart_readonly) < 0) || (SMR_DW_INT(m, &ramcart_size) < 0) || (SMR_B_INT(m, &ramcart_size_kb) < 0) || (SMR_BA(m, ramcart, 2) < 0)) { goto fail; } ramcart_ram = lib_malloc(ramcart_size); if (SMR_BA(m, ramcart_ram, ramcart_size) < 0) { snapshot_module_close(m); lib_free(ramcart_ram); ramcart_ram = NULL; return -1; } snapshot_module_close(m); /* ramcart_filetype = 0; */ ramcart_write_image = 0; ramcart_enabled = 1; /* FIXME: ugly code duplication to avoid cart_config_changed calls */ ramcart_io1_list_item = io_source_register(&ramcart_io1_device); ramcart_io2_list_item = io_source_register(&ramcart_io2_device); if (export_add(&export_res) < 0) { lib_free(ramcart_ram); ramcart_ram = NULL; io_source_unregister(ramcart_io1_list_item); io_source_unregister(ramcart_io2_list_item); ramcart_io1_list_item = NULL; ramcart_io2_list_item = NULL; ramcart_enabled = 0; return -1; } return 0; fail: snapshot_module_close(m); return -1; }
int ted_snapshot_read_module(snapshot_t *s) { BYTE major_version, minor_version; int i; snapshot_module_t *m; m = snapshot_module_open(s, snap_module_name, &major_version, &minor_version); if (m == NULL) { return -1; } if (major_version > SNAP_MAJOR || minor_version > SNAP_MINOR) { log_error(ted.log, "Snapshot module version (%d.%d) newer than %d.%d.", major_version, minor_version, SNAP_MAJOR, SNAP_MINOR); goto fail; } /* FIXME: initialize changes? */ if (0 || SMR_DW(m, &ted.last_emulate_line_clk) < 0 /* AllowBadLines */ || SMR_B_INT(m, &ted.allow_bad_lines) < 0 /* BadLine */ || SMR_B_INT(m, &ted.bad_line) < 0 /* Blank */ || SMR_B_INT(m, &ted.raster.blank_enabled) < 0 /* ColorBuf */ || SMR_BA(m, ted.cbuf, 40) < 0 /* IdleState */ || SMR_B_INT(m, &ted.idle_state) < 0 /* MatrixBuf */ || SMR_BA(m, ted.vbuf, 40) < 0 ) { goto fail; } /* Read the current raster line and the current raster cycle. As they are a function of `clk', this is just a sanity check. */ { WORD RasterLine; BYTE RasterCycle; if (SMR_B(m, &RasterCycle) < 0 || SMR_W(m, &RasterLine) < 0) { goto fail; } DBG(("TED read snapshot at clock: %d cycle: %d (%d) tedline: %d (%d) rasterline: %d\n", maincpu_clk, TED_RASTER_CYCLE(maincpu_clk), RasterCycle, TED_RASTER_Y(maincpu_clk), RasterLine, ted.raster.current_line)); if (RasterCycle != (BYTE)TED_RASTER_CYCLE(maincpu_clk)) { log_error(ted.log, "Not matching raster cycle (%d) in snapshot; should be %d.", RasterCycle, TED_RASTER_CYCLE(maincpu_clk)); goto fail; } if (RasterLine != (WORD)TED_RASTER_Y(maincpu_clk)) { log_error(ted.log, "Not matching raster line (%d) in snapshot; should be %d.", RasterLine, TED_RASTER_Y(maincpu_clk)); goto fail; } } for (i = 0; i < 0x40; i++) { if (SMR_B(m, &ted.regs[i]) < 0 /* Registers */) { goto fail; } } if (0 || SMR_DW_INT(m, (int*)&ted.ted_raster_counter) < 0 /* Vc */ || SMR_W_INT(m, &ted.mem_counter) < 0 /* VcInc */ || SMR_B_INT(m, &ted.mem_counter_inc) < 0 /* VcBase */ || SMR_W_INT(m, &ted.memptr) < 0 /* VideoInt */ || SMR_B_INT(m, &ted.irq_status) < 0) { goto fail; } /* FIXME: Recalculate alarms and derived values. */ ted_irq_set_raster_line(ted.regs[0x0b] | ((ted.regs[0x0a] & 1) << 8)); ted_update_memory_ptrs(TED_RASTER_CYCLE(maincpu_clk)); ted.raster.xsmooth = ted.regs[0x07] & 0x7; ted.raster.ysmooth = ted.regs[0x06] & 0x7; ted.raster.current_line = TED_RASTER_Y(maincpu_clk); /* FIXME? */ /* Update colors. */ ted.raster.border_color = ted.regs[0x19]; ted.raster.background_color = ted.regs[0x15]; ted.ext_background_color[0] = ted.regs[0x16]; ted.ext_background_color[1] = ted.regs[0x17]; ted.ext_background_color[2] = ted.regs[0x18]; ted.raster.blank = !(ted.regs[0x06] & 0x10); if (TED_IS_ILLEGAL_MODE (ted.raster.video_mode)) { ted.raster.idle_background_color = 0; ted.force_black_overscan_background_color = 1; } else { ted.raster.idle_background_color = ted.raster.background_color; ted.force_black_overscan_background_color = 0; } if (ted.regs[0x06] & 0x8) { ted.raster.display_ystart = ted.row_25_start_line; ted.raster.display_ystop = ted.row_25_stop_line; } else { ted.raster.display_ystart = ted.row_24_start_line; ted.raster.display_ystop = ted.row_24_stop_line; } if (ted.regs[0x07] & 0x8) { ted.raster.display_xstart = TED_40COL_START_PIXEL; ted.raster.display_xstop = TED_40COL_STOP_PIXEL; } else { ted.raster.display_xstart = TED_38COL_START_PIXEL; ted.raster.display_xstop = TED_38COL_STOP_PIXEL; } /* `ted.raster.draw_idle_state', `ted.raster.open_right_border' and `ted.raster.open_left_border' should be needed, but they would only affect the current ted.raster line, and would not cause any difference in timing. So who cares. */ /* FIXME: `ted.ycounter_reset_checked'? */ /* FIXME: `ted.force_display_state'? */ ted.memory_fetch_done = 0; /* FIXME? */ ted_update_video_mode(TED_RASTER_CYCLE(maincpu_clk)); ted.draw_clk = maincpu_clk + (ted.draw_cycle - TED_RASTER_CYCLE(maincpu_clk)); ted.last_emulate_line_clk = ted.draw_clk - ted.cycles_per_line; alarm_set(ted.raster_draw_alarm, ted.draw_clk); { DWORD dw; if (SMR_DW(m, &dw) < 0) { /* FetchEventTick */ goto fail; } ted.fetch_clk = maincpu_clk + dw; alarm_set(ted.raster_fetch_alarm, ted.fetch_clk); } if (ted.irq_status & 0x80) { interrupt_restore_irq(maincpu_int_status, ted.int_num, 1); } raster_force_repaint(&ted.raster); DBG(("TED: snapshot loaded.\n")); return 0; fail: if (m != NULL) { snapshot_module_close(m); } log_error(ted.log, "could not load TED snapshot."); return -1; }
int vic20cart_snapshot_read_module(snapshot_t *s) { BYTE vmajor, vminor; snapshot_module_t *m; int new_cart_type, cartridge_reset; BYTE i; BYTE number_of_carts; int cart_ids[VIC20CART_DUMP_MAX_CARTS]; m = snapshot_module_open(s, SNAP_MODULE_NAME, &vmajor, &vminor); if (m == NULL) { return -1; } if (vmajor != VIC20CART_DUMP_VER_MAJOR) { goto fail; } if (SMR_DW_INT(m, &new_cart_type) < 0) { goto fail; } if (SMR_B(m, &number_of_carts) < 0) { goto fail; } /* Not much to do if no carts in snapshot */ if (number_of_carts == 0) { return snapshot_module_close(m); } if (number_of_carts > VIC20CART_DUMP_MAX_CARTS) { DBG(("CART snapshot read: carts %i > max %i\n", number_of_carts, VIC20CART_DUMP_MAX_CARTS)); goto fail; } /* Read cart IDs */ for (i = 0; i < number_of_carts; i++) { if (SMR_DW_INT(m, &cart_ids[i]) < 0) { goto fail; } } snapshot_module_close(m); /* disable cartridge reset while detaching old cart */ resources_get_int("CartridgeReset", &cartridge_reset); resources_set_int("CartridgeReset", 0); cartridge_detach_image(-1); resources_set_int("CartridgeReset", cartridge_reset); /* disallow "set as default" and write back */ cartridge_is_from_snapshot = 1; vic20cart_type = new_cart_type; mem_cartridge_type = new_cart_type; /* Read individual cart data */ for (i = 0; i < number_of_carts; i++) { switch (cart_ids[i]) { case CARTRIDGE_VIC20_FINAL_EXPANSION: if (finalexpansion_snapshot_read_module(s) < 0) { return -1; } break; case CARTRIDGE_VIC20_IO2_RAM: if (ioramcart_io2_snapshot_read_module(s) < 0) { return -1; } break; case CARTRIDGE_VIC20_IO3_RAM: if (ioramcart_io3_snapshot_read_module(s) < 0) { return -1; } break; case CARTRIDGE_VIC20_MEGACART: if (megacart_snapshot_read_module(s) < 0) { return -1; } break; case CARTRIDGE_VIC20_UM: if (vic_um_snapshot_read_module(s) < 0) { return -1; } break; case CARTRIDGE_VIC20_IEEE488: if (vic20_ieee488_snapshot_read_module(s) < 0) { return -1; } break; #ifdef HAVE_MIDI case CARTRIDGE_MIDI_MAPLIN: if (vic20_midi_snapshot_read_module(s) < 0) { return -1; } break; #endif case CARTRIDGE_VIC20_SIDCART: if (sidcart_snapshot_read_module(s) < 0) { return -1; } break; case CARTRIDGE_VIC20_FP: if (vic_fp_snapshot_read_module(s) < 0) { return -1; } break; case CARTRIDGE_ACIA: if (aciacart_snapshot_read_module(s) < 0) { return -1; } break; case CARTRIDGE_DIGIMAX: if (digimax_snapshot_read_module(s) < 0) { return -1; } break; case CARTRIDGE_DS12C887RTC: if (ds12c887rtc_snapshot_read_module(s) < 0) { return -1; } break; case CARTRIDGE_GEORAM: if (georam_read_snapshot_module(s) < 0) { return -1; } break; case CARTRIDGE_SFX_SOUND_EXPANDER: if (sfx_soundexpander_snapshot_read_module(s) < 0) { return -1; } break; case CARTRIDGE_SFX_SOUND_SAMPLER: if (sfx_soundsampler_snapshot_read_module(s) < 0) { return -1; } break; #ifdef HAVE_TFE case CARTRIDGE_TFE: if (tfe_snapshot_read_module(s) < 0) { return -1; } break; #endif } } if (vic20cart_type == CARTRIDGE_VIC20_GENERIC) { if (generic_snapshot_read_module(s) < 0) { return -1; } } return 0; fail: snapshot_module_close(m); return -1; }
int vicii_snapshot_read_module(snapshot_t *s) { BYTE major_version, minor_version; int i; snapshot_module_t *m; m = snapshot_module_open(s, snap_module_name, &major_version, &minor_version); if (m == NULL) return -1; if (major_version > SNAP_MAJOR || minor_version > SNAP_MINOR) { log_error(vicii.log, "Snapshot module version (%d.%d) newer than %d.%d.", major_version, minor_version, SNAP_MAJOR, SNAP_MINOR); goto fail; } /* FIXME: initialize changes? */ if (0 /* AllowBadLines */ || SMR_B_INT(m, &vicii.allow_bad_lines) < 0 /* BadLine */ || SMR_B_INT(m, &vicii.bad_line) < 0 /* Blank */ || SMR_B_INT(m, &vicii.raster.blank_enabled) < 0 /* ColorBuf */ || SMR_BA(m, vicii.cbuf, 40) < 0 /* IdleState */ || SMR_B_INT(m, &vicii.idle_state) < 0 /* LPTrigger */ || SMR_B_INT(m, &vicii.light_pen.triggered) < 0 /* LPX */ || SMR_B_INT(m, &vicii.light_pen.x) < 0 /* LPY */ || SMR_B_INT(m, &vicii.light_pen.y) < 0 /* MatrixBuf */ || SMR_BA(m, vicii.vbuf, 40) < 0 /* NewSpriteDmaMask */ || SMR_B(m, &vicii.raster.sprite_status->new_dma_msk) < 0) goto fail; { DWORD RamBase; if (SMR_DW(m, &RamBase) < 0) goto fail; vicii.ram_base_phi1 = mem_ram + RamBase; } /* Read the current raster line and the current raster cycle. As they are a function of `clk', this is just a sanity check. */ { WORD RasterLine; BYTE RasterCycle; if (SMR_B(m, &RasterCycle) < 0 || SMR_W(m, &RasterLine) < 0) goto fail; if (RasterCycle != (BYTE)VICII_RASTER_CYCLE(maincpu_clk)) { log_error(vicii.log, "Not matching raster cycle (%d) in snapshot; should be %d.", RasterCycle, VICII_RASTER_CYCLE(maincpu_clk)); goto fail; } if (RasterLine != (WORD)VICII_RASTER_Y(maincpu_clk)) { log_error(vicii.log, "VIC-II: Not matching raster line (%d) in snapshot; should be %d.", RasterLine, VICII_RASTER_Y(maincpu_clk)); goto fail; } } for (i = 0; i < 0x50; i++) if (SMR_B(m, &vicii.regs[i]) < 0 /* Registers */ ) goto fail; if (0 /* DTV stuff */ || SMR_DW_INT(m, &vicii.counta) < 0 || SMR_DW_INT(m, &vicii.counta_mod) < 0 || SMR_DW_INT(m, &vicii.counta_step) < 0 || SMR_DW_INT(m, &vicii.countb) < 0 || SMR_DW_INT(m, &vicii.countb_mod) < 0 || SMR_DW_INT(m, &vicii.countb_step) < 0 || SMR_DW_INT(m, (int *)&vicii.extended_enable) < 0 || SMR_DW_INT(m, (int *)&vicii.extended_lockout) < 0 || SMR_DW_INT(m, (int *)&vicii.badline_disable) < 0 || SMR_DW_INT(m, (int *)&vicii.colorfetch_disable) < 0 || SMR_DW_INT(m, (int *)&vicii.overscan) < 0 || SMR_DW_INT(m, (int *)&vicii.high_color) < 0 || SMR_DW_INT(m, (int *)&vicii.border_off) < 0 || SMR_DW_INT(m, &vicii.raster_irq_offset) < 0 || SMR_DW_INT(m, &vicii.raster_irq_prevent) < 0 || SMR_BA(m, vicii.dtvpalette, 256) < 0 /* SbCollMask */ || SMR_B(m, &vicii.sprite_background_collisions) < 0 /* SpriteDmaMask */ || SMR_B(m, &vicii.raster.sprite_status->dma_msk) < 0 /* SsCollMask */ || SMR_B(m, &vicii.sprite_sprite_collisions) < 0 /* VBank */ || SMR_W_INT(m, &vicii.vbank_phi1) < 0 /* Vc */ || SMR_W_INT(m, &vicii.mem_counter) < 0 /* VcInc */ || SMR_B_INT(m, &vicii.mem_counter_inc) < 0 /* VcBase */ || SMR_W_INT(m, &vicii.memptr) < 0 /* VideoInt */ || SMR_B_INT(m, &vicii.irq_status) < 0) goto fail; for (i = 0; i < 8; i++) { if (0 /* SpriteXMemPtr */ || SMR_B_INT(m, &vicii.raster.sprite_status->sprites[i].memptr) < 0 /* SpriteXMemPtrInc */ || SMR_B_INT(m, &vicii.raster.sprite_status->sprites[i].memptr_inc) < 0 /* SpriteXExpFlipFlop */ || SMR_B_INT(m, &vicii.raster.sprite_status->sprites[i].exp_flag) < 0 ) goto fail; } /* FIXME: Recalculate alarms and derived values. */ #if 1 if (vicii.raster_irq_prevent) { vicii.raster_irq_clk = CLOCK_MAX; alarm_unset(vicii.raster_irq_alarm); } else { /* We cannot use vicii_irq_set_raster_line as this would delay an alarm on line 0 for one frame */ unsigned int line = vicii.regs[0x12] | ((vicii.regs[0x11] & 0x80) << 1); if (line < (unsigned int)vicii.screen_height) { vicii.raster_irq_clk = (VICII_LINE_START_CLK(maincpu_clk) + VICII_RASTER_IRQ_DELAY - INTERRUPT_DELAY + (vicii.cycles_per_line * line)); vicii.raster_irq_clk += vicii.raster_irq_offset; /* Raster interrupts on line 0 are delayed by 1 cycle. */ if (line == 0) vicii.raster_irq_clk++; alarm_set(vicii.raster_irq_alarm, vicii.raster_irq_clk); } else { vicii.raster_irq_clk = CLOCK_MAX; alarm_unset(vicii.raster_irq_alarm); } vicii.raster_irq_line = line; } #else vicii_irq_set_raster_line(vicii.regs[0x12] | ((vicii.regs[0x11] & 0x80) << 1)); #endif /* compatibility with older versions */ vicii.ram_base_phi2 = vicii.ram_base_phi1; vicii.vbank_phi2 = vicii.vbank_phi1; vicii_update_memory_ptrs(VICII_RASTER_CYCLE(maincpu_clk)); /* Update sprite parameters. We had better do this manually, or the VIC-II emulation could be quite upset. */ { BYTE msk; for (i = 0, msk = 0x1; i < 8; i++, msk <<= 1) { raster_sprite_t *sprite; int tmp; sprite = vicii.raster.sprite_status->sprites + i; /* X/Y coordinates. */ tmp = vicii.regs[i * 2] + ((vicii.regs[0x10] & msk) ? 0x100 : 0); /* (-0xffff makes sure it's updated NOW.) */ vicii_sprites_set_x_position(i, tmp, -0xffff); sprite->y = (int)vicii.regs[i * 2 + 1]; sprite->x_expanded = (int)(vicii.regs[0x1d] & msk); sprite->y_expanded = (int)(vicii.regs[0x17] & msk); sprite->multicolor = (int)(vicii.regs[0x1c] & msk); sprite->in_background = (int)(vicii.regs[0x1b] & msk); sprite->color = (int) vicii.dtvpalette[vicii.regs[0x27 + i] & 0xf]; sprite->dma_flag = (int)(vicii.raster.sprite_status->new_dma_msk & msk); } } vicii.sprite_fetch_msk = vicii.raster.sprite_status->new_dma_msk; vicii.sprite_fetch_clk = VICII_LINE_START_CLK(maincpu_clk) + vicii.sprite_fetch_cycle - vicii.cycles_per_line; /* calculate the sprite_fetch_idx */ { const vicii_sprites_fetch_t *sf; sf = vicii_sprites_fetch_table[vicii.sprite_fetch_msk]; i = 0; while (sf[i].cycle >= 0 && sf[i].cycle + vicii.sprite_fetch_cycle <= vicii.cycles_per_line) { i++; } vicii.sprite_fetch_idx = i; } vicii.raster.xsmooth = vicii.regs[0x16] & 0x7; vicii.raster.sprite_xsmooth = vicii.regs[0x16] & 0x7; vicii.raster.ysmooth = vicii.regs[0x11] & 0x7; vicii.raster.current_line = VICII_RASTER_Y(maincpu_clk); /* FIXME? */ vicii.raster.sprite_status->visible_msk = vicii.regs[0x15]; /* Update colors. */ vicii.raster.border_color = vicii.dtvpalette[vicii.regs[0x20]]; vicii.raster.background_color = vicii.dtvpalette[vicii.regs[0x21]]; vicii.ext_background_color[0] = vicii.dtvpalette[vicii.regs[0x22]]; vicii.ext_background_color[1] = vicii.dtvpalette[vicii.regs[0x23]]; vicii.ext_background_color[2] = vicii.dtvpalette[vicii.regs[0x24]]; vicii.raster.sprite_status->mc_sprite_color_1 = vicii.dtvpalette[vicii.regs[0x25] & 0xf]; vicii.raster.sprite_status->mc_sprite_color_2 = vicii.dtvpalette[vicii.regs[0x26] & 0xf]; vicii.raster.blank = !(vicii.regs[0x11] & 0x10); if (VICII_IS_ILLEGAL_MODE(vicii.raster.video_mode)) { vicii.raster.idle_background_color = 0; vicii.force_black_overscan_background_color = 1; } else { vicii.raster.idle_background_color = vicii.raster.background_color; vicii.force_black_overscan_background_color = 0; } if (vicii.regs[0x11] & 0x8) { vicii.raster.display_ystart = vicii.row_25_start_line; vicii.raster.display_ystop = vicii.row_25_stop_line; } else { vicii.raster.display_ystart = vicii.row_24_start_line; vicii.raster.display_ystop = vicii.row_24_stop_line; } if (vicii.regs[0x16] & 0x8) { vicii.raster.display_xstart = VICII_40COL_START_PIXEL; vicii.raster.display_xstop = VICII_40COL_STOP_PIXEL; } else { vicii.raster.display_xstart = VICII_38COL_START_PIXEL; vicii.raster.display_xstop = VICII_38COL_STOP_PIXEL; } /* `vicii.raster.draw_idle_state', `vicii.raster.open_right_border' and `vicii.raster.open_left_border' should be needed, but they would only affect the current vicii.raster line, and would not cause any difference in timing. So who cares. */ /* FIXME: `vicii.ycounter_reset_checked'? */ /* FIXME: `vicii.force_display_state'? */ vicii.memory_fetch_done = 0; /* FIXME? */ vicii_update_video_mode(VICII_RASTER_CYCLE(maincpu_clk)); vicii_store(0x3c, (BYTE)vicii.regs[0x3c]); vicii.draw_clk = maincpu_clk + (vicii.draw_cycle - VICII_RASTER_CYCLE(maincpu_clk)); vicii.last_emulate_line_clk = vicii.draw_clk - vicii.cycles_per_line; alarm_set(vicii.raster_draw_alarm, vicii.draw_clk); { DWORD dw; BYTE b; if (0 || SMR_DW(m, &dw) < 0 /* FetchEventTick */ || SMR_B(m, &b) < 0 /* FetchEventType */ ) goto fail; vicii.fetch_clk = maincpu_clk + dw; vicii.fetch_idx = b; alarm_set(vicii.raster_fetch_alarm, vicii.fetch_clk); } if (vicii.irq_status & 0x80) interrupt_restore_irq(maincpu_int_status, vicii.int_num, 1); /* added in version 1.1 of snapshot format */ if (minor_version > 0) { DWORD RamBase; if (0 || SMR_DW(m, &RamBase) < 0 || SMR_W_INT(m, &vicii.vbank_phi2) < 0 /* VBank */ ) goto fail; vicii.ram_base_phi2 = mem_ram + RamBase; vicii_update_memory_ptrs(VICII_RASTER_CYCLE(maincpu_clk)); } raster_force_repaint(&vicii.raster); snapshot_module_close(m); return 0; fail: if (m != NULL) snapshot_module_close(m); return -1; }