Skip to content

Instantly share code, notes, and snippets.

@nurpax
Created April 25, 2018 07:49
Show Gist options
  • Save nurpax/71aa57be0b819163bbf950715b41e3e0 to your computer and use it in GitHub Desktop.
Save nurpax/71aa57be0b819163bbf950715b41e3e0 to your computer and use it in GitHub Desktop.
vice 3.1 snapshot.c copy
/*
* snapshot.c - Implementation of machine snapshot files.
*
* Written by
* Ettore Perazzoli <[email protected]>
* Marco van den Heuvel <[email protected]>
*
* This file is part of VICE, the Versatile Commodore Emulator.
* See README for copyright notice.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA.
*
*/
#include "vice.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "archdep.h"
#include "lib.h"
#include "ioutil.h"
#include "log.h"
#include "snapshot.h"
#ifdef USE_SVN_REVISION
#include "svnversion.h"
#endif
#include "translate.h"
#include "types.h"
#include "uiapi.h"
#include "version.h"
#include "vsync.h"
#include "zfile.h"
static int snapshot_error = SNAPSHOT_NO_ERROR;
static char *current_module = NULL;
static char read_name[SNAPSHOT_MACHINE_NAME_LEN];
static char *current_machine_name = NULL;
static char *current_filename = NULL;
char snapshot_magic_string[] = "VICE Snapshot File\032";
char snapshot_version_magic_string[] = "VICE Version\032";
#define SNAPSHOT_MAGIC_LEN 19
#define SNAPSHOT_VERSION_MAGIC_LEN 13
struct snapshot_module_s {
/* File descriptor. */
FILE *file;
/* Flag: are we writing it? */
int write_mode;
/* Size of the module. */
DWORD size;
/* Offset of the module in the file. */
long offset;
/* Offset of the size field in the file. */
long size_offset;
};
struct snapshot_s {
/* File descriptor. */
FILE *file;
/* Offset of the first module. */
long first_module_offset;
/* Flag: are we writing it? */
int write_mode;
};
/* ------------------------------------------------------------------------- */
static int snapshot_write_byte(FILE *f, BYTE data)
{
if (fputc(data, f) == EOF) {
snapshot_error = SNAPSHOT_WRITE_EOF_ERROR;
return -1;
}
return 0;
}
static int snapshot_write_word(FILE *f, WORD data)
{
if (snapshot_write_byte(f, (BYTE)(data & 0xff)) < 0
|| snapshot_write_byte(f, (BYTE)(data >> 8)) < 0) {
return -1;
}
return 0;
}
static int snapshot_write_dword(FILE *f, DWORD data)
{
if (snapshot_write_word(f, (WORD)(data & 0xffff)) < 0
|| snapshot_write_word(f, (WORD)(data >> 16)) < 0) {
return -1;
}
return 0;
}
static int snapshot_write_double(FILE *f, double data)
{
BYTE *byte_data = (BYTE *)&data;
int i;
for (i = 0; i < sizeof(double); i++) {
if (snapshot_write_byte(f, byte_data[i]) < 0) {
return -1;
}
}
return 0;
}
static int snapshot_write_padded_string(FILE *f, const char *s, BYTE pad_char,
int len)
{
int i, found_zero;
BYTE c;
for (i = found_zero = 0; i < len; i++) {
if (!found_zero && s[i] == 0) {
found_zero = 1;
}
c = found_zero ? (BYTE)pad_char : (BYTE) s[i];
if (snapshot_write_byte(f, c) < 0) {
return -1;
}
}
return 0;
}
static int snapshot_write_byte_array(FILE *f, const BYTE *data, unsigned int num)
{
if (num > 0 && fwrite(data, (size_t)num, 1, f) < 1) {
snapshot_error = SNAPSHOT_WRITE_BYTE_ARRAY_ERROR;
return -1;
}
return 0;
}
static int snapshot_write_word_array(FILE *f, const WORD *data, unsigned int num)
{
unsigned int i;
for (i = 0; i < num; i++) {
if (snapshot_write_word(f, data[i]) < 0) {
return -1;
}
}
return 0;
}
static int snapshot_write_dword_array(FILE *f, const DWORD *data, unsigned int num)
{
unsigned int i;
for (i = 0; i < num; i++) {
if (snapshot_write_dword(f, data[i]) < 0) {
return -1;
}
}
return 0;
}
static int snapshot_write_string(FILE *f, const char *s)
{
size_t len, i;
len = s ? (strlen(s) + 1) : 0; /* length includes nullbyte */
if (snapshot_write_word(f, (WORD)len) < 0) {
return -1;
}
for (i = 0; i < len; i++) {
if (snapshot_write_byte(f, s[i]) < 0) {
return -1;
}
}
return (int)(len + sizeof(WORD));
}
static int snapshot_read_byte(FILE *f, BYTE *b_return)
{
int c;
c = fgetc(f);
if (c == EOF) {
snapshot_error = SNAPSHOT_READ_EOF_ERROR;
return -1;
}
*b_return = (BYTE)c;
return 0;
}
static int snapshot_read_word(FILE *f, WORD *w_return)
{
BYTE lo, hi;
if (snapshot_read_byte(f, &lo) < 0 || snapshot_read_byte(f, &hi) < 0) {
return -1;
}
*w_return = lo | (hi << 8);
return 0;
}
static int snapshot_read_dword(FILE *f, DWORD *dw_return)
{
WORD lo, hi;
if (snapshot_read_word(f, &lo) < 0 || snapshot_read_word(f, &hi) < 0) {
return -1;
}
*dw_return = lo | (hi << 16);
return 0;
}
static int snapshot_read_double(FILE *f, double *d_return)
{
int i;
int c;
double val;
BYTE *byte_val = (BYTE *)&val;
for (i = 0; i < sizeof(double); i++) {
c = fgetc(f);
if (c == EOF) {
snapshot_error = SNAPSHOT_READ_EOF_ERROR;
return -1;
}
byte_val[i] = (BYTE)c;
}
*d_return = val;
return 0;
}
static int snapshot_read_byte_array(FILE *f, BYTE *b_return, unsigned int num)
{
if (num > 0 && fread(b_return, (size_t)num, 1, f) < 1) {
snapshot_error = SNAPSHOT_READ_BYTE_ARRAY_ERROR;
return -1;
}
return 0;
}
static int snapshot_read_word_array(FILE *f, WORD *w_return, unsigned int num)
{
unsigned int i;
for (i = 0; i < num; i++) {
if (snapshot_read_word(f, w_return + i) < 0) {
return -1;
}
}
return 0;
}
static int snapshot_read_dword_array(FILE *f, DWORD *dw_return, unsigned int num)
{
unsigned int i;
for (i = 0; i < num; i++) {
if (snapshot_read_dword(f, dw_return + i) < 0) {
return -1;
}
}
return 0;
}
static int snapshot_read_string(FILE *f, char **s)
{
int i, len;
WORD w;
char *p = NULL;
/* first free the previous string */
lib_free(*s);
*s = NULL; /* don't leave a bogus pointer */
if (snapshot_read_word(f, &w) < 0) {
return -1;
}
len = (int)w;
if (len) {
p = lib_malloc(len);
*s = p;
for (i = 0; i < len; i++) {
if (snapshot_read_byte(f, (BYTE *)(p + i)) < 0) {
p[0] = 0;
return -1;
}
}
p[len - 1] = 0; /* just to be save */
}
return 0;
}
/* ------------------------------------------------------------------------- */
int snapshot_module_write_byte(snapshot_module_t *m, BYTE b)
{
if (snapshot_write_byte(m->file, b) < 0) {
return -1;
}
m->size++;
return 0;
}
int snapshot_module_write_word(snapshot_module_t *m, WORD w)
{
if (snapshot_write_word(m->file, w) < 0) {
return -1;
}
m->size += 2;
return 0;
}
int snapshot_module_write_dword(snapshot_module_t *m, DWORD dw)
{
if (snapshot_write_dword(m->file, dw) < 0) {
return -1;
}
m->size += 4;
return 0;
}
int snapshot_module_write_double(snapshot_module_t *m, double db)
{
if (snapshot_write_double(m->file, db) < 0) {
return -1;
}
m->size += 8;
return 0;
}
int snapshot_module_write_padded_string(snapshot_module_t *m, const char *s, BYTE pad_char, int len)
{
if (snapshot_write_padded_string(m->file, s, (BYTE)pad_char, len) < 0) {
return -1;
}
m->size += len;
return 0;
}
int snapshot_module_write_byte_array(snapshot_module_t *m, const BYTE *b, unsigned int num)
{
if (snapshot_write_byte_array(m->file, b, num) < 0) {
return -1;
}
m->size += num;
return 0;
}
int snapshot_module_write_word_array(snapshot_module_t *m, const WORD *w, unsigned int num)
{
if (snapshot_write_word_array(m->file, w, num) < 0) {
return -1;
}
m->size += num * sizeof(WORD);
return 0;
}
int snapshot_module_write_dword_array(snapshot_module_t *m, const DWORD *dw, unsigned int num)
{
if (snapshot_write_dword_array(m->file, dw, num) < 0) {
return -1;
}
m->size += num * sizeof(DWORD);
return 0;
}
int snapshot_module_write_string(snapshot_module_t *m, const char *s)
{
int len;
len = snapshot_write_string(m->file, s);
if (len < 0) {
snapshot_error = SNAPSHOT_ILLEGAL_STRING_LENGTH_ERROR;
return -1;
}
m->size += len;
return 0;
}
/* ------------------------------------------------------------------------- */
int snapshot_module_read_byte(snapshot_module_t *m, BYTE *b_return)
{
if (ftell(m->file) + sizeof(BYTE) > m->offset + m->size) {
snapshot_error = SNAPSHOT_READ_OUT_OF_BOUNDS_ERROR;
return -1;
}
return snapshot_read_byte(m->file, b_return);
}
int snapshot_module_read_word(snapshot_module_t *m, WORD *w_return)
{
if (ftell(m->file) + sizeof(WORD) > m->offset + m->size) {
snapshot_error = SNAPSHOT_READ_OUT_OF_BOUNDS_ERROR;
return -1;
}
return snapshot_read_word(m->file, w_return);
}
int snapshot_module_read_dword(snapshot_module_t *m, DWORD *dw_return)
{
if (ftell(m->file) + sizeof(DWORD) > m->offset + m->size) {
snapshot_error = SNAPSHOT_READ_OUT_OF_BOUNDS_ERROR;
return -1;
}
return snapshot_read_dword(m->file, dw_return);
}
int snapshot_module_read_double(snapshot_module_t *m, double *db_return)
{
if (ftell(m->file) + sizeof(double) > m->offset + m->size) {
snapshot_error = SNAPSHOT_READ_OUT_OF_BOUNDS_ERROR;
return -1;
}
return snapshot_read_double(m->file, db_return);
}
int snapshot_module_read_byte_array(snapshot_module_t *m, BYTE *b_return, unsigned int num)
{
if ((long)(ftell(m->file) + num) > (long)(m->offset + m->size)) {
snapshot_error = SNAPSHOT_READ_OUT_OF_BOUNDS_ERROR;
return -1;
}
return snapshot_read_byte_array(m->file, b_return, num);
}
int snapshot_module_read_word_array(snapshot_module_t *m, WORD *w_return, unsigned int num)
{
if ((long)(ftell(m->file) + num * sizeof(WORD)) > (long)(m->offset + m->size)) {
snapshot_error = SNAPSHOT_READ_OUT_OF_BOUNDS_ERROR;
return -1;
}
return snapshot_read_word_array(m->file, w_return, num);
}
int snapshot_module_read_dword_array(snapshot_module_t *m, DWORD *dw_return, unsigned int num)
{
if ((long)(ftell(m->file) + num * sizeof(DWORD)) > (long)(m->offset + m->size)) {
snapshot_error = SNAPSHOT_READ_OUT_OF_BOUNDS_ERROR;
return -1;
}
return snapshot_read_dword_array(m->file, dw_return, num);
}
int snapshot_module_read_string(snapshot_module_t *m, char **charp_return)
{
if (ftell(m->file) + sizeof(WORD) > m->offset + m->size) {
snapshot_error = SNAPSHOT_READ_OUT_OF_BOUNDS_ERROR;
return -1;
}
return snapshot_read_string(m->file, charp_return);
}
int snapshot_module_read_byte_into_int(snapshot_module_t *m, int *value_return)
{
BYTE b;
if (snapshot_module_read_byte(m, &b) < 0) {
return -1;
}
*value_return = (int)b;
return 0;
}
int snapshot_module_read_word_into_int(snapshot_module_t *m, int *value_return)
{
WORD b;
if (snapshot_module_read_word(m, &b) < 0) {
return -1;
}
*value_return = (int)b;
return 0;
}
int snapshot_module_read_dword_into_ulong(snapshot_module_t *m, unsigned long *value_return)
{
DWORD b;
if (snapshot_module_read_dword(m, &b) < 0) {
return -1;
}
*value_return = (unsigned long)b;
return 0;
}
int snapshot_module_read_dword_into_int(snapshot_module_t *m, int *value_return)
{
DWORD b;
if (snapshot_module_read_dword(m, &b) < 0) {
return -1;
}
*value_return = (int)b;
return 0;
}
int snapshot_module_read_dword_into_uint(snapshot_module_t *m, unsigned int *value_return)
{
DWORD b;
if (snapshot_module_read_dword(m, &b) < 0) {
return -1;
}
*value_return = (unsigned int)b;
return 0;
}
/* ------------------------------------------------------------------------- */
snapshot_module_t *snapshot_module_create(snapshot_t *s, const char *name, BYTE major_version, BYTE minor_version)
{
snapshot_module_t *m;
current_module = (char *)name;
m = lib_malloc(sizeof(snapshot_module_t));
m->file = s->file;
m->offset = ftell(s->file);
if (m->offset == -1) {
snapshot_error = SNAPSHOT_ILLEGAL_OFFSET_ERROR;
lib_free(m);
return NULL;
}
m->write_mode = 1;
if (snapshot_write_padded_string(s->file, name, (BYTE)0, SNAPSHOT_MODULE_NAME_LEN) < 0
|| snapshot_write_byte(s->file, major_version) < 0
|| snapshot_write_byte(s->file, minor_version) < 0
|| snapshot_write_dword(s->file, 0) < 0) {
return NULL;
}
m->size = ftell(s->file) - m->offset;
m->size_offset = ftell(s->file) - sizeof(DWORD);
return m;
}
snapshot_module_t *snapshot_module_open(snapshot_t *s, const char *name, BYTE *major_version_return, BYTE *minor_version_return)
{
snapshot_module_t *m;
char n[SNAPSHOT_MODULE_NAME_LEN];
unsigned int name_len = (unsigned int)strlen(name);
current_module = (char *)name;
if (fseek(s->file, s->first_module_offset, SEEK_SET) < 0) {
snapshot_error = SNAPSHOT_FIRST_MODULE_NOT_FOUND_ERROR;
return NULL;
}
m = lib_malloc(sizeof(snapshot_module_t));
m->file = s->file;
m->write_mode = 0;
m->offset = s->first_module_offset;
/* Search for the module name. This is quite inefficient, but I don't
think we care. */
while (1) {
if (snapshot_read_byte_array(s->file, (BYTE *)n,
SNAPSHOT_MODULE_NAME_LEN) < 0
|| snapshot_read_byte(s->file, major_version_return) < 0
|| snapshot_read_byte(s->file, minor_version_return) < 0
|| snapshot_read_dword(s->file, &m->size)) {
snapshot_error = SNAPSHOT_MODULE_HEADER_READ_ERROR;
goto fail;
}
/* Found? */
if (memcmp(n, name, name_len) == 0
&& (name_len == SNAPSHOT_MODULE_NAME_LEN || n[name_len] == 0)) {
break;
}
m->offset += m->size;
if (fseek(s->file, m->offset, SEEK_SET) < 0) {
snapshot_error = SNAPSHOT_MODULE_NOT_FOUND_ERROR;
goto fail;
}
}
m->size_offset = ftell(s->file) - sizeof(DWORD);
return m;
fail:
fseek(s->file, s->first_module_offset, SEEK_SET);
lib_free(m);
return NULL;
}
int snapshot_module_close(snapshot_module_t *m)
{
/* Backpatch module size if writing. */
if (m->write_mode
&& (fseek(m->file, m->size_offset, SEEK_SET) < 0
|| snapshot_write_dword(m->file, m->size) < 0)) {
snapshot_error = SNAPSHOT_MODULE_CLOSE_ERROR;
return -1;
}
/* Skip module. */
if (fseek(m->file, m->offset + m->size, SEEK_SET) < 0) {
snapshot_error = SNAPSHOT_MODULE_SKIP_ERROR;
return -1;
}
lib_free(m);
return 0;
}
/* ------------------------------------------------------------------------- */
snapshot_t *snapshot_create(const char *filename, BYTE major_version, BYTE minor_version, const char *snapshot_machine_name)
{
FILE *f;
snapshot_t *s;
unsigned char viceversion[4] = { VERSION_RC_NUMBER };
current_filename = (char *)filename;
f = fopen(filename, MODE_WRITE);
if (f == NULL) {
snapshot_error = SNAPSHOT_CANNOT_CREATE_SNAPSHOT_ERROR;
return NULL;
}
/* Magic string. */
if (snapshot_write_padded_string(f, snapshot_magic_string, (BYTE)0, SNAPSHOT_MAGIC_LEN) < 0) {
snapshot_error = SNAPSHOT_CANNOT_WRITE_MAGIC_STRING_ERROR;
goto fail;
}
/* Version number. */
if (snapshot_write_byte(f, major_version) < 0
|| snapshot_write_byte(f, minor_version) < 0) {
snapshot_error = SNAPSHOT_CANNOT_WRITE_VERSION_ERROR;
goto fail;
}
/* Machine. */
if (snapshot_write_padded_string(f, snapshot_machine_name, (BYTE)0, SNAPSHOT_MACHINE_NAME_LEN) < 0) {
snapshot_error = SNAPSHOT_CANNOT_WRITE_MACHINE_NAME_ERROR;
goto fail;
}
/* VICE version and revision */
if (snapshot_write_padded_string(f, snapshot_version_magic_string, (BYTE)0, SNAPSHOT_VERSION_MAGIC_LEN) < 0) {
snapshot_error = SNAPSHOT_CANNOT_WRITE_MAGIC_STRING_ERROR;
goto fail;
}
if (snapshot_write_byte(f, viceversion[0]) < 0
|| snapshot_write_byte(f, viceversion[1]) < 0
|| snapshot_write_byte(f, viceversion[2]) < 0
|| snapshot_write_byte(f, viceversion[3]) < 0
#ifdef USE_SVN_REVISION
|| snapshot_write_dword(f, VICE_SVN_REV_NUMBER) < 0) {
#else
|| snapshot_write_dword(f, 0) < 0) {
#endif
snapshot_error = SNAPSHOT_CANNOT_WRITE_VERSION_ERROR;
goto fail;
}
s = lib_malloc(sizeof(snapshot_t));
s->file = f;
s->first_module_offset = ftell(f);
s->write_mode = 1;
return s;
fail:
fclose(f);
ioutil_remove(filename);
return NULL;
}
/* informal only, used by the error message created below */
static unsigned char snapshot_viceversion[4];
static DWORD snapshot_vicerevision;
snapshot_t *snapshot_open(const char *filename, BYTE *major_version_return, BYTE *minor_version_return, const char *snapshot_machine_name)
{
FILE *f;
char magic[SNAPSHOT_MAGIC_LEN];
snapshot_t *s = NULL;
int machine_name_len;
size_t offs;
current_machine_name = (char *)snapshot_machine_name;
current_filename = (char *)filename;
current_module = NULL;
f = zfile_fopen(filename, MODE_READ);
if (f == NULL) {
snapshot_error = SNAPSHOT_CANNOT_OPEN_FOR_READ_ERROR;
return NULL;
}
/* Magic string. */
if (snapshot_read_byte_array(f, (BYTE *)magic, SNAPSHOT_MAGIC_LEN) < 0
|| memcmp(magic, snapshot_magic_string, SNAPSHOT_MAGIC_LEN) != 0) {
snapshot_error = SNAPSHOT_MAGIC_STRING_MISMATCH_ERROR;
goto fail;
}
/* Version number. */
if (snapshot_read_byte(f, major_version_return) < 0
|| snapshot_read_byte(f, minor_version_return) < 0) {
snapshot_error = SNAPSHOT_CANNOT_READ_VERSION_ERROR;
goto fail;
}
/* Machine. */
if (snapshot_read_byte_array(f, (BYTE *)read_name, SNAPSHOT_MACHINE_NAME_LEN) < 0) {
snapshot_error = SNAPSHOT_CANNOT_READ_MACHINE_NAME_ERROR;
goto fail;
}
/* Check machine name. */
machine_name_len = (int)strlen(snapshot_machine_name);
if (memcmp(read_name, snapshot_machine_name, machine_name_len) != 0
|| (machine_name_len != SNAPSHOT_MODULE_NAME_LEN
&& read_name[machine_name_len] != 0)) {
snapshot_error = SNAPSHOT_MACHINE_MISMATCH_ERROR;
goto fail;
}
/* VICE version and revision */
memset(snapshot_viceversion, 0, 4);
snapshot_vicerevision = 0;
offs = ftell(f);
if (snapshot_read_byte_array(f, (BYTE *)magic, SNAPSHOT_VERSION_MAGIC_LEN) < 0
|| memcmp(magic, snapshot_version_magic_string, SNAPSHOT_VERSION_MAGIC_LEN) != 0) {
/* old snapshots do not contain VICE version */
fseek(f, offs, SEEK_SET);
log_warning(LOG_DEFAULT, "attempting to load pre 2.4.30 snapshot");
} else {
/* actually read the version */
if (snapshot_read_byte(f, &snapshot_viceversion[0]) < 0
|| snapshot_read_byte(f, &snapshot_viceversion[1]) < 0
|| snapshot_read_byte(f, &snapshot_viceversion[2]) < 0
|| snapshot_read_byte(f, &snapshot_viceversion[3]) < 0
|| snapshot_read_dword(f, &snapshot_vicerevision) < 0) {
snapshot_error = SNAPSHOT_CANNOT_READ_VERSION_ERROR;
goto fail;
}
}
s = lib_malloc(sizeof(snapshot_t));
s->file = f;
s->first_module_offset = ftell(f);
s->write_mode = 0;
vsync_suspend_speed_eval();
return s;
fail:
fclose(f);
return NULL;
}
int snapshot_close(snapshot_t *s)
{
int retval;
if (!s->write_mode) {
if (zfile_fclose(s->file) == EOF) {
snapshot_error = SNAPSHOT_READ_CLOSE_EOF_ERROR;
retval = -1;
} else {
retval = 0;
}
} else {
if (fclose(s->file) == EOF) {
snapshot_error = SNAPSHOT_WRITE_CLOSE_EOF_ERROR;
retval = -1;
} else {
retval = 0;
}
}
lib_free(s);
return retval;
}
static void display_error_with_vice_version(char *text, char *filename)
{
char *vmessage = lib_malloc(0x100);
char *message = lib_malloc(0x100 + strlen(text));
if ((snapshot_viceversion[0] == 0) && (snapshot_viceversion[1] == 0)) {
/* generic message for the case when no version is present in the snapshot */
strcpy(vmessage, translate_text(IDGS_SNAPSHOT_OLD_VICE_VERSION));
} else {
sprintf(vmessage, translate_text(IDGS_SNAPSHOT_VICE_VERSION),
snapshot_viceversion[0], snapshot_viceversion[1], snapshot_viceversion[2]);
if (snapshot_vicerevision != 0) {
sprintf(message, " (r%d)", (int)snapshot_vicerevision);
strcat(vmessage, message);
}
}
sprintf(message, "%s\n\n%s.", text, vmessage);
ui_error(message, filename);
lib_free(message);
lib_free(vmessage);
}
void snapshot_display_error(void)
{
switch (snapshot_error) {
default:
case SNAPSHOT_NO_ERROR:
break;
case SNAPSHOT_WRITE_EOF_ERROR:
if (current_module) {
ui_error(translate_text(IDGS_EOF_WRITING_MODULE_S_SNAPSHOT_S), current_module, current_filename);
} else {
ui_error(translate_text(IDGS_EOF_WRITING_SNAPSHOT_S), current_filename);
}
break;
case SNAPSHOT_WRITE_BYTE_ARRAY_ERROR:
if (current_module) {
ui_error(translate_text(IDGS_ERROR_WRITING_ARRAY_MODULE_S_SNAPSHOT_S), current_module, current_filename);
} else {
ui_error(translate_text(IDGS_ERROR_WRITING_ARRAY_SNAPSHOT_S), current_filename);
}
break;
case SNAPSHOT_READ_EOF_ERROR:
if (current_module) {
ui_error(translate_text(IDGS_EOF_READING_MODULE_S_SNAPSHOT_S), current_module, current_filename);
} else {
ui_error(translate_text(IDGS_EOF_READING_SNAPSHOT_S), current_filename);
}
break;
case SNAPSHOT_READ_BYTE_ARRAY_ERROR:
if (current_module) {
ui_error(translate_text(IDGS_ERROR_READING_ARRAY_MODULE_S_SNAPSHOT_S), current_module, current_filename);
} else {
ui_error(translate_text(IDGS_ERROR_READING_ARRAY_SNAPSHOT_S), current_filename);
}
break;
case SNAPSHOT_ILLEGAL_STRING_LENGTH_ERROR:
if (current_module) {
ui_error(translate_text(IDGS_ERROR_WRITING_STRING_MODULE_S_SNAPSHOT_S), current_module, current_filename);
} else {
ui_error(translate_text(IDGS_ERROR_WRITING_STRING_SNAPSHOT_S), current_filename);
}
break;
case SNAPSHOT_READ_OUT_OF_BOUNDS_ERROR:
if (current_module) {
ui_error(translate_text(IDGS_OUT_OF_BOUNDS_READING_MODULE_S_SNAPSHOT_S), current_module, current_filename);
} else {
ui_error(translate_text(IDGS_OUT_OF_BOUNDS_READING_SNAPSHOT_S), current_filename);
}
break;
case SNAPSHOT_ILLEGAL_OFFSET_ERROR:
ui_error(translate_text(IDGS_ILLEGAL_OFFSET_CREATE_MODULE_S_SNAPSHOT_S), current_module, current_filename);
break;
case SNAPSHOT_FIRST_MODULE_NOT_FOUND_ERROR:
ui_error(translate_text(IDGS_CANNOT_FIND_1ST_MODULE_SNAPSHOT_S), current_filename);
break;
case SNAPSHOT_MODULE_HEADER_READ_ERROR:
ui_error(translate_text(IDGS_ERROR_MODULE_HEADER_SNAPSHOT_S), current_filename);
break;
case SNAPSHOT_MODULE_NOT_FOUND_ERROR:
ui_error(translate_text(IDGS_CANNOT_FIND_MODULE_S_SNAPSHOT_S), current_module, current_filename);
break;
case SNAPSHOT_MODULE_CLOSE_ERROR:
ui_error(translate_text(IDGS_ERROR_CLOSING_MODULE_S_SNAPSHOT_S), current_module, current_filename);
break;
case SNAPSHOT_MODULE_SKIP_ERROR:
ui_error(translate_text(IDGS_ERROR_SKIPPING_MODULE_SNAPSHOT_S), current_filename);
break;
case SNAPSHOT_CANNOT_CREATE_SNAPSHOT_ERROR:
ui_error(translate_text(IDGS_CANNOT_CREATE_SNAPSHOT_S), current_filename);
break;
case SNAPSHOT_CANNOT_WRITE_MAGIC_STRING_ERROR:
ui_error(translate_text(IDGS_CANNOT_WRITE_MAGIC_STRING_SNAPSHOT_S), current_filename);
break;
case SNAPSHOT_CANNOT_WRITE_VERSION_ERROR:
ui_error(translate_text(IDGS_CANNOT_WRITE_VERSION_SNAPSHOT_S), current_filename);
break;
case SNAPSHOT_CANNOT_WRITE_MACHINE_NAME_ERROR:
ui_error(translate_text(IDGS_CANNOT_WRITE_MACHINE_NAME_SNAPSHOT_S), current_filename);
break;
case SNAPSHOT_CANNOT_OPEN_FOR_READ_ERROR:
ui_error(translate_text(IDGS_CANNOT_OPEN_SNAPSHOT_S_READING), current_filename);
break;
case SNAPSHOT_MAGIC_STRING_MISMATCH_ERROR:
ui_error(translate_text(IDGS_MAGIC_STRING_MISMATCH_SNAPSHOT_S), current_filename);
break;
case SNAPSHOT_CANNOT_READ_VERSION_ERROR:
ui_error(translate_text(IDGS_CANNOT_READ_VERSION_SNAPSHOT_S), current_filename);
break;
case SNAPSHOT_CANNOT_READ_MACHINE_NAME_ERROR:
ui_error(translate_text(IDGS_CANNOT_READ_MACHINE_NAME_SNAPSHOT_S), current_filename);
break;
case SNAPSHOT_MACHINE_MISMATCH_ERROR:
ui_error(translate_text(IDGS_WRONG_MACHINE_TYPE_SNAPSHOT_S), current_filename, read_name, current_machine_name);
break;
case SNAPSHOT_READ_CLOSE_EOF_ERROR:
case SNAPSHOT_WRITE_CLOSE_EOF_ERROR:
ui_error(translate_text(IDGS_EOF_CLOSING_SNAPSHOT_S), current_filename);
break;
case SNAPSHOT_MODULE_HIGHER_VERSION:
display_error_with_vice_version(translate_text(IDGS_SNAPSHOT_HIGHER_VERSION), current_filename);
break;
case SNAPSHOT_MODULE_INCOMPATIBLE:
display_error_with_vice_version(translate_text(IDGS_INCOMPATIBLE_SNAPSHOT), current_filename);
break;
}
}
void snapshot_set_error(int error)
{
snapshot_error = error;
}
int snapshot_version_at_least(BYTE major_version, BYTE minor_version, BYTE major_version_required, BYTE minor_version_required)
{
if (major_version != major_version_required) {
return 0;
}
if (minor_version >= minor_version_required) {
return 1;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment