void check_prefs_changed_carts(int in_memory_reset);
int action_replay_unload(int in_memory_reset);
-static int stored_picasso_on;
+static int stored_picasso_on = -1;
static void cartridge_enter(void)
{
static void cartridge_exit(void)
{
#ifdef PICASSO96
- picasso_requested_on = stored_picasso_on;
+ if (stored_picasso_on >= 0)
+ picasso_requested_on = stored_picasso_on;
+ stored_picasso_on = -1;
#endif
}
filesys_install_code ();
#endif
+ uae_boot_rom_size = here() - RTAREA_BASE;
init_extended_traps();
}
#if defined(ENFORCER)
#include "enforcer.h"
#endif
+#include "gayle.h"
STATIC_INLINE int nocustom(void)
{
}
inputdevice_hsync ();
+ mbdmac_hsync();
hsync_counter++;
//copper_check (2);
uae_sem_init (&gui_sem, 0, 1);
#ifdef PICASSO96
- InitPicasso96 ();
- picasso_on = 0;
- picasso_requested_on = 0;
- gfx_set_picasso_state (0);
+ if (savestate_state != STATE_RESTORE) {
+ InitPicasso96 ();
+ picasso_on = 0;
+ picasso_requested_on = 0;
+ gfx_set_picasso_state (0);
+ }
#endif
xlinebuffer = gfxvidinfo.bufmem;
inhibit_frame = 0;
uaecptr ROM_filesys_diagentry;
uaecptr ROM_hardfile_resname, ROM_hardfile_resid;
uaecptr ROM_hardfile_init;
-int uae_boot_rom;
+int uae_boot_rom, uae_boot_rom_size; /* size = code size only */
/* ********************************************************** */
save_u32 (fastmem_start);
save_u32 (z3fastmem_start);
save_u32 (gfxmem_start);
- *len = 4 + 4 + 4;
+ save_u32 (RTAREA_BASE);
+ *len = 4 + 4 + 4 + 4;
return dstbak;
}
fastmem_start = restore_u32 ();
z3fastmem_start = restore_u32 ();
gfxmem_start = restore_u32 ();
+ restore_u32();
return src;
}
uaecptr filesys_initcode;
static uae_u32 fsdevname, filesys_configdev;
+static int filesys_in_interrupt;
#define FS_STARTUP 0
#define FS_GO_DOWN 1
return my_strdup (rel);
}
+static void init_child_aino_tree(Unit *unit, a_inode *base, a_inode *aino)
+{
+ /* Update tree structure */
+ aino->parent = base;
+ aino->child = 0;
+ aino->sibling = base->child;
+ base->child = aino;
+ aino->next = aino->prev = 0;
+ aino->volflags = unit->volflags;
+}
+
static void init_child_aino (Unit *unit, a_inode *base, a_inode *aino)
{
aino->uniq = ++a_uniq;
unit->total_locked_ainos++;
base->locked_children++;
}
- /* Update tree structure */
- aino->parent = base;
- aino->child = 0;
- aino->sibling = base->child;
- base->child = aino;
- aino->next = aino->prev = 0;
- aino->volflags = unit->volflags;
+ init_child_aino_tree(unit, base, aino);
aino_test_init (aino);
aino_test (aino);
return curr;
}
+
+static uae_u32 notifyhash (char *s)
+{
+ uae_u32 hash = 0;
+ while (*s)
+ hash = (hash << 5) + *s++;
+ return hash % NOTIFY_HASH_SIZE;
+}
+
+static Notify *new_notify (Unit *unit, char *name)
+{
+ Notify *n = xmalloc(sizeof(Notify));
+ uae_u32 hash = notifyhash (name);
+ n->next = unit->notifyhash[hash];
+ unit->notifyhash[hash] = n;
+ n->partname = name;
+ return n;
+}
+
+static void free_notify_item(Notify *n)
+{
+ xfree(n->fullname);
+ xfree(n->partname);
+ xfree(n);
+}
+
+static void free_notify (Unit *unit, int hash, Notify *n)
+{
+ Notify *n1, *prev = 0;
+ for (n1 = unit->notifyhash[hash]; n1; n1 = n1->next) {
+ if (n == n1) {
+ if (prev)
+ prev->next = n->next;
+ else
+ unit->notifyhash[hash] = n->next;
+ break;
+ }
+ prev = n1;
+ }
+}
+
static void startup_update_unit (Unit *unit, UnitInfo *uinfo)
{
if (!unit)
unit->total_locked_ainos = 0;
unit->next_exkey = 1;
unit->keys = 0;
+ for (i = 0; i < NOTIFY_HASH_SIZE; i++) {
+ Notify *n = unit->notifyhash[i];
+ while (n) {
+ Notify *n2 = n;
+ n = n->next;
+ xfree(n2->fullname);
+ xfree(n2->partname);
+ xfree(n2);
+ }
+ unit->notifyhash[i] = 0;
+ }
unit->rootnode.aname = uinfo->volname;
unit->rootnode.nname = uinfo->rootdir;
return lock;
}
-static uae_u32 notifyhash (char *s)
-{
- uae_u32 hash = 0;
- while (*s) hash = (hash << 5) + *s++;
- return hash % NOTIFY_HASH_SIZE;
-}
-
-static Notify *new_notify (Unit *unit, char *name)
-{
- Notify *n = xmalloc(sizeof(Notify));
- int hash = notifyhash (name);
- n->next = unit->notifyhash[hash];
- unit->notifyhash[hash] = n;
- n->partname = name;
- return n;
-}
-
-static void free_notify (Unit *unit, int hash, Notify *n)
-{
- Notify *n1, *prev = 0;
- for (n1 = unit->notifyhash[hash]; n1; n1 = n1->next) {
- if (n == n1) {
- if (prev)
- prev->next = n->next;
- else
- unit->notifyhash[hash] = n->next;
- break;
- }
- prev = n1;
- }
- xfree(n);
-}
-
#define NOTIFY_CLASS 0x40000000
#define NOTIFY_CODE 0x1234
/* Clear the interrupt flag _before_ we do any processing.
* That way, we can get too many interrupts, but never not
* enough. */
+ filesys_in_interrupt++;
uae_int_requested = 0;
unit_no = 0;
return 1;
break;
case 4:
/* Exit the interrupt, and release the single-threading lock. */
+ filesys_in_interrupt--;
uae_sem_post (&singlethread_int_sem);
break;
void filesys_start_threads (void)
{
- UnitInfo *uip;
int i;
- uip = mountinfo.ui;
+ filesys_in_interrupt = 0;
for (i = 0; i < MAX_FILESYSTEM_UNITS; i++) {
- UnitInfo *ui = &uip[i];
+ UnitInfo *ui = &mountinfo.ui[i];
if (!ui->open)
continue;
ui->unit_pipe = 0;
if (is_hardfile (i) == FILESYS_VIRTUAL) {
ui->unit_pipe = (smp_comm_pipe *)xmalloc (sizeof (smp_comm_pipe));
ui->back_pipe = (smp_comm_pipe *)xmalloc (sizeof (smp_comm_pipe));
- init_comm_pipe (uip[i].unit_pipe, 100, 3);
- init_comm_pipe (uip[i].back_pipe, 100, 1);
- uae_start_thread ("filesys", filesys_thread, (void *)(uip + i), &uip[i].tid);
+ init_comm_pipe (ui->unit_pipe, 100, 3);
+ init_comm_pipe (ui->back_pipe, 100, 1);
+ uae_start_thread ("filesys", filesys_thread, (void *)ui, &ui->tid);
}
#endif
if (savestate_state == STATE_RESTORE)
- startup_update_unit (uip->self, uip);
+ startup_update_unit (ui->self, ui);
}
}
filesys_configdev = m68k_areg (&context->regs, 3);
init_filesys_diagentry ();
- uae_sem_init (&singlethread_int_sem, 0, 1);
- uae_sem_init (&test_sem, 0, 1);
if (ROM_hardfile_resid != 0) {
/* Build a struct Resident. This will set up and initialize
* the uae.device */
TRACE (("Installing filesystem\n"));
+ uae_sem_init (&singlethread_int_sem, 0, 1);
+ uae_sem_init (&test_sem, 0, 1);
+
ROM_filesys_resname = ds("UAEunixfs.resource");
ROM_filesys_resid = ds("UAE unixfs 0.4");
}
#include "od-win32/win32_filesys.c"
+static uae_u8 *restore_filesys_hardfile (UnitInfo *ui, uae_u8 *src)
+{
+ struct hardfiledata *hfd = &ui->hf;
+ char *s;
+
+ hfd->size = restore_u64();
+ hfd->offset = restore_u64();
+ hfd->nrcyls = restore_u32();
+ hfd->secspertrack = restore_u32();
+ hfd->surfaces = restore_u32();
+ hfd->reservedblocks = restore_u32();
+ hfd->blocksize = restore_u32();
+ hfd->readonly = restore_u32();
+ hfd->flags = restore_u32();
+ hfd->cylinders = restore_u32();
+ hfd->sectors = restore_u32();
+ hfd->heads = restore_u32();
+ s = restore_string();
+ strcpy (hfd->vendor_id, s);
+ xfree(s);
+ s = restore_string();
+ strcpy (hfd->product_id, s);
+ xfree(s);
+ s = restore_string();
+ strcpy (hfd->product_rev, s);
+ xfree(s);
+ s = restore_string();
+ strcpy (hfd->device_name, s);
+ xfree(s);
+ return src;
+}
+
+static uae_u8 *save_filesys_hardfile (UnitInfo *ui, uae_u8 *dst)
+{
+ struct hardfiledata *hfd = &ui->hf;
+
+ save_u64 (hfd->size);
+ save_u64 (hfd->offset);
+ save_u32 (hfd->nrcyls);
+ save_u32 (hfd->secspertrack);
+ save_u32 (hfd->surfaces);
+ save_u32 (hfd->reservedblocks);
+ save_u32 (hfd->blocksize);
+ save_u32 (hfd->readonly);
+ save_u32 (hfd->flags);
+ save_u32 (hfd->cylinders);
+ save_u32 (hfd->sectors);
+ save_u32 (hfd->heads);
+ save_string (hfd->vendor_id);
+ save_string (hfd->product_id);
+ save_string (hfd->product_rev);
+ save_string (hfd->device_name);
+ return dst;
+}
+
+static a_inode *restore_filesys_get_base(Unit *u, char *npath)
+{
+ char *path, *p, *p2;
+ a_inode *a;
+ int cnt, err, i;
+
+ /* no '/' = parent is root */
+ if (!strchr(npath, '/'))
+ return &u->rootnode;
+
+ /* iterate from root to last to previous path part,
+ * create ainos if not already created.
+ */
+ path = xcalloc(strlen(npath) + 2, 1);
+ cnt = 1;
+ for (;;) {
+ strcpy (path, npath);
+ strcat (path, "/");
+ p = path;
+ for (i = 0; i < cnt ;i++) {
+ if (i > 0)
+ p++;
+ while (*p != '/' && *p != 0)
+ p++;
+ }
+ if (*p) {
+ *p = 0;
+ err = 0;
+ get_aino (u, &u->rootnode, path, &err);
+ if (err) {
+ write_log("*** FS: missing path '%s'!\n", path);
+ return NULL;
+ }
+ cnt++;
+ } else {
+ break;
+ }
+ }
+
+ /* find base (parent) of last path part */
+ strcpy (path, npath);
+ p = path;
+ a = u->rootnode.child;
+ for (;;) {
+ if (*p == 0) {
+ write_log("*** FS: base aino NOT found '%s' ('%s')\n", a->nname, npath);
+ xfree (path);
+ return NULL;
+ }
+ p2 = p;
+ while(*p2 != '/' && *p2 != '\\' && *p2 != 0)
+ p2++;
+ *p2 = 0;
+ while (a) {
+ if (!same_aname(p, a->aname)) {
+ a = a->sibling;
+ continue;
+ }
+ p = p2 + 1;
+ if (*p == 0) {
+ write_log("FS: base aino found '%s' ('%s')\n", a->nname, npath);
+ xfree (path);
+ return a;
+ }
+ a = a->child;
+ break;
+ }
+ if (!a) {
+ write_log("*** FS: path part '%s' not found ('%s')\n", p, npath);
+ xfree (path);
+ return NULL;
+ }
+ }
+}
+
+static char *makenativepath(UnitInfo *ui, char *apath)
+{
+ int i;
+ char *pn;
+ /* create native path. FIXME: handle 'illegal' characters */
+ pn = xcalloc (strlen (apath) + 1 + strlen (ui->rootdir) + 1, 1);
+ sprintf (pn, "%s/%s", ui->rootdir, apath);
+ if (FSDB_DIR_SEPARATOR != '/') {
+ for (i = 0; i < strlen (pn); i++) {
+ if (pn[i] == '/')
+ pn[i] = FSDB_DIR_SEPARATOR;
+ }
+ }
+ return pn;
+}
+
+static uae_u8 *restore_aino(UnitInfo *ui, Unit *u, uae_u8 *src)
+{
+ char *p, *p2, *pn;
+ uae_u32 flags;
+ int missing;
+ a_inode *base, *a;
+
+ missing = 0;
+ a = xcalloc (sizeof (a_inode), 1);
+ a->uniq = restore_u64 ();
+ a->locked_children = restore_u32 ();
+ a->exnext_count = restore_u32 ();
+ a->shlock = restore_u32 ();
+ flags = restore_u32 ();
+ if (flags & 1)
+ a->elock = 1;
+ /* full Amiga-side path without drive, eg. "C/SetPatch" */
+ p = restore_string ();
+ /* root (p = volume label) */
+ if (a->uniq == 0) {
+ a->nname = my_strdup(ui->rootdir);
+ a->aname = p;
+ a->dir = 1;
+ if (ui->volflags < 0) {
+ write_log ("FS: Volume '%s' ('%s') missing!\n", a->aname, a->nname);
+ } else {
+ a->volflags = ui->volflags;
+ recycle_aino (u, a);
+ write_log("FS: Lock (root) '%s' ('%s')\n", a->aname, a->nname);
+ }
+ return src;
+ }
+ p2 = strrchr(p, '/');
+ if (p2)
+ p2++;
+ else
+ p2 = p;
+ pn = makenativepath(ui, p);
+ a->nname = pn;
+ a->aname = my_strdup(p2);
+ /* find parent of a->aname (Already restored previously. I hope..) */
+ if (p2 != p)
+ p2[-1] = 0;
+ base = restore_filesys_get_base(u, p);
+ xfree(p);
+ if (flags & 2) {
+ a->dir = 1;
+ if (!my_existsdir(a->nname))
+ write_log("*** FS: Directory '%s' missing!\n", a->nname);
+ else
+ fsdb_clean_dir (a);
+ } else {
+ if (!my_existsfile(a->nname))
+ write_log("*** FS: File '%s' missing!\n", a->nname);
+ }
+ if (base) {
+ fsdb_fill_file_attrs (base, a);
+ init_child_aino_tree (u, base, a);
+ } else {
+ write_log("*** FS: parent directory missing '%s' ('%s')\n", a->aname, a->nname);
+ missing = 1;
+ }
+ if (missing) {
+ write_log("*** FS: Lock restore failed '%s' ('%s')\n", a->aname, a->nname);
+ xfree (a->nname);
+ xfree (a->aname);
+ xfree (a);
+ } else {
+ write_log("FS: Lock '%s' ('%s')\n", a->aname, a->nname);
+ recycle_aino (u, a);
+ }
+ return src;
+}
+
+static uae_u8 *restore_key(UnitInfo *ui, Unit *u, uae_u8 *src)
+{
+ int savedsize, uniq;
+ char *p, *pn;
+ mode_t openmode;
+ DWORD err;
+ int missing;
+ a_inode *a;
+ Key *k;
+
+ missing = 0;
+ k = xcalloc(sizeof(Key), 1);
+ k->uniq = restore_u64();
+ k->file_pos = restore_u32();
+ k->createmode = restore_u32();
+ k->dosmode = restore_u32();
+ savedsize = restore_u32();
+ uniq = restore_u64();
+ p = restore_string();
+ pn = makenativepath (ui, p);
+ openmode = ((k->dosmode & A_FIBF_READ) == 0 ? O_WRONLY
+ : (k->dosmode & A_FIBF_WRITE) == 0 ? O_RDONLY
+ : O_RDWR);
+ write_log("FS: open file '%s' ('%s'), pos=%d\n", p, pn, k->file_pos);
+ a = get_aino (u, &u->rootnode, p, &err);
+ if (!a)
+ write_log ("*** FS: Open file aino creation failed '%s'\n", p);
+ missing = 1;
+ if (a) {
+ missing = 0;
+ k->aino = a;
+ if (a->uniq != uniq)
+ write_log("*** FS: Open file '%s' aino id %d != %d\n", p, uniq, a->uniq);
+ if (!my_existsfile(pn)) {
+ write_log("*** FS: Open file '%s' is missing, creating dummy file!\n", p);
+ k->fd = my_open (pn, openmode | O_CREAT |O_BINARY);
+ if (k->fd) {
+ uae_u8 *buf = xcalloc (10000, 1);
+ int sp = savedsize;
+ while (sp) {
+ int s = sp >= 10000 ? 10000 : sp;
+ my_write(k->fd, buf, s);
+ sp -= s;
+ }
+ xfree(buf);
+ write_log("*** FS: dummy file created\n");
+ } else {
+ write_log("*** FS: Open file '%s', couldn't create dummy file!\n", p);
+ }
+ } else {
+ k->fd = my_open (pn, openmode | O_BINARY);
+ }
+ if (!k->fd) {
+ write_log("*** FS: Open file '%s' failed to open!\n", p);
+ missing = 1;
+ } else {
+ size_t s;
+ s = my_lseek (k->fd, 0, SEEK_END);
+ if (s != savedsize)
+ write_log("FS: restored file '%s' size changed! orig=%d, now=%d!!\n", p, savedsize, s);
+ if (k->file_pos > s) {
+ write_log("FS: restored filepos larger than size of file '%s'!! %d > %d\n", p, k->file_pos, s);
+ k->file_pos = s;
+ }
+ my_lseek (k->fd, k->file_pos, SEEK_SET);
+ }
+ }
+ xfree (p);
+ if (missing) {
+ xfree(k);
+ } else {
+ k->next = u->keys;
+ u->keys = k;
+ }
+ return src;
+}
+
+static uae_u8 *restore_notify(UnitInfo *ui, Unit *u, uae_u8 *src)
+{
+ Notify *n = xcalloc (sizeof (Notify), 1);
+ uae_u32 hash;
+ char *s;
+
+ n->notifyrequest = restore_u32();
+ s = restore_string();
+ n->fullname = xmalloc (strlen(ui->volname) + 2 + strlen(s) + 1);
+ sprintf (n->fullname, "%s:%s", ui->volname, s);
+ xfree(s);
+ s = strrchr(n->fullname, '/');
+ if (s)
+ s++;
+ else
+ s = n->fullname;
+ n->partname = my_strdup(s);
+ hash = notifyhash (n->fullname);
+ n->next = u->notifyhash[hash];
+ u->notifyhash[hash] = n;
+ write_log("FS: notify %08.8X '%s' '%s'\n", n->notifyrequest, n->fullname, n->partname);
+ return src;
+}
+
+static uae_u8 *restore_exkey(UnitInfo *ui, Unit *u, uae_u8 *src)
+{
+ restore_u64();
+ restore_u64();
+ restore_u64();
+ return src;
+}
+
static uae_u8 *restore_filesys_virtual (UnitInfo *ui, uae_u8 *src)
{
Unit *u = startup_create_unit (ui);
int cnt;
- a_uniq = restore_u64 ();
- key_uniq = restore_u64 ();
u->dosbase = restore_u32 ();
u->volume = restore_u32 ();
u->port = restore_u32 ();
u->cmds_sent = restore_u64 ();
u->cmds_complete = restore_u64 ();
u->cmds_acked = restore_u64 ();
+ u->next_exkey = restore_u32 ();
+ u->total_locked_ainos = restore_u32 ();
+ u->volflags = ui->volflags;
+
cnt = restore_u32 ();
- while (cnt-- > 0) {
- restore_u64 ();
- restore_u32 ();
- restore_u32 ();
- restore_u32 ();
- xfree (restore_string ());
- }
+ write_log("FS: restoring %d locks\n", cnt);
+ while (cnt-- > 0)
+ src = restore_aino(ui, u, src);
+
+ cnt = restore_u32 ();
+ write_log("FS: restoring %d open files\n", cnt);
+ while (cnt-- > 0)
+ src = restore_key(ui, u, src);
+
+ cnt = restore_u32 ();
+ write_log("FS: restoring %d notifications\n", cnt);
+ while (cnt-- > 0)
+ src = restore_notify (ui, u, src);
+
+ cnt = restore_u32 ();
+ write_log("FS: restoring %d exkeys\n", cnt);
+ while (cnt-- > 0)
+ src = restore_exkey (ui, u, src);
+
return src;
}
+static char *getfullaname(a_inode *a)
+{
+ char *p = xmalloc (2000);
+ int first = 1;
+
+ memset(p, 0, 2000);
+ while (a) {
+ int len = strlen(a->aname);
+ memmove (p + len + 1, p, strlen(p) + 1);
+ memcpy (p, a->aname, strlen(a->aname));
+ if (!first)
+ p[len] = '/';
+ first = 0;
+ a = a->parent;
+ if (a && a->uniq == 0)
+ return p;
+ }
+ return p;
+}
+
+/* scan and save all Lock()'d files */
+static int recurse_aino (UnitInfo *ui, a_inode *a, int cnt, uae_u8 **dstp)
+{
+ uae_u8 *dst = NULL;
+ int dirty = 0;
+ a_inode *a2 = a;
+
+ if (dstp)
+ dst = *dstp;
+ while (a) {
+ if (a->elock || a->shlock || a->uniq == 0) {
+ if (dst) {
+ char *fn = getfullaname(a);
+ write_log("%04x '%s' s=%d e=%d d=%d\n", a->uniq, fn, a->shlock, a->elock, a->dir);
+ save_u64 (a->uniq);
+ save_u32 (a->locked_children);
+ save_u32 (a->exnext_count);
+ save_u32 (a->shlock);
+ save_u32 ((a->elock ? 1 : 0) | (a->dir ? 2 : 0));
+ save_string (fn);
+ xfree(fn);
+ }
+ cnt++;
+ }
+ if (a->dirty)
+ dirty = 1;
+ if (a->child)
+ cnt = recurse_aino (ui, a->child, cnt, &dst);
+ a = a->sibling;
+ }
+ if (dirty && a2->parent)
+ fsdb_dir_writeback (a2->parent);
+ if (dst)
+ *dstp = dst;
+ return cnt;
+}
+
+static uae_u8 *save_key(uae_u8 *dst, Key *k)
+{
+ char *fn = getfullaname(k->aino);
+ int size;
+ save_u64 (k->uniq);
+ save_u32 (k->file_pos);
+ save_u32 (k->createmode);
+ save_u32 (k->dosmode);
+ size = my_lseek(k->fd, 0, SEEK_END);
+ save_u32 (size);
+ save_u64 (k->aino->uniq);
+ my_lseek(k->fd, k->file_pos, SEEK_SET);
+ save_string (fn);
+ write_log("'%s' uniq=%d size=%d seekpos=%d mode=%d dosmode=%d\n",
+ fn, k->uniq, size, k->file_pos, k->createmode, k->dosmode);
+ xfree(fn);
+ return dst;
+}
+
+static uae_u8 *save_notify (UnitInfo *ui, uae_u8 *dst, Notify *n)
+{
+ char *s;
+ save_u32(n->notifyrequest);
+ s = n->fullname;
+ if (strlen(s) >= strlen(ui->volname) && !memcmp(n->fullname, ui->volname, strlen(ui->volname)))
+ s = n->fullname + strlen(ui->volname) + 1;
+ save_string(s);
+ write_log("FS: notify %08.8X '%s'\n", n->notifyrequest, n->fullname);
+ return dst;
+}
+
+static uae_u8 *save_exkey (uae_u8 *dst, ExamineKey *ek)
+{
+ save_u64(ek->uniq);
+ save_u64(ek->aino->uniq);
+ save_u64(ek->curr_file->uniq);
+ return dst;
+}
+
static uae_u8 *save_filesys_virtual (UnitInfo *ui, uae_u8 *dst)
{
Unit *u = ui->self;
Key *k;
- int cnt;
+ int cnt, i, j;
write_log("FSSAVE: '%s'\n", ui->devname);
- save_u64 (a_uniq);
- save_u64 (key_uniq);
save_u32 (u->dosbase);
save_u32 (u->volume);
save_u32 (u->port);
save_u64 (u->cmds_sent);
save_u64 (u->cmds_complete);
save_u64 (u->cmds_acked);
+ save_u32 (u->next_exkey);
+ save_u32 (u->total_locked_ainos);
+ cnt = recurse_aino (ui, &u->rootnode, 0, NULL);
+ save_u32 (cnt);
+ write_log("%d open locks\n", cnt);
+ cnt = recurse_aino (ui, &u->rootnode, 0, &dst);
cnt = 0;
for (k = u->keys; k; k = k->next)
cnt++;
save_u32 (cnt);
write_log("%d open files\n", cnt);
- for (k = u->keys; k; k = k->next) {
- save_u64 (k->uniq);
- save_u32 (k->file_pos);
- save_u32 (k->createmode);
- save_u32 (k->dosmode);
- save_string (k->aino->nname);
- write_log("'%s' uniq=%d seekpos=%d mode=%d dosmode=%d\n",
- k->aino->nname, k->uniq, k->file_pos, k->createmode, k->dosmode);
+ for (k = u->keys; k; k = k->next)
+ dst = save_key (dst, k);
+ for (j = 0; j < 2; j++) {
+ cnt = 0;
+ for (i = 0; i < NOTIFY_HASH_SIZE; i++) {
+ Notify *n = u->notifyhash[i];
+ while (n) {
+ if (j > 0)
+ dst = save_notify (ui, dst, n);
+ cnt++;
+ n = n->next;
+ }
+ }
+ if (j == 0) {
+ save_u32 (cnt);
+ write_log("%d notify requests\n", cnt);
+ }
+ }
+ for (j = 0; j < 2; j++) {
+ cnt = 0;
+ for (i = 0; i < EXKEYS; i++) {
+ ExamineKey *ek = &u->examine_keys[i];
+ if (ek->uniq) {
+ cnt++;
+ if (j > 0)
+ dst = save_exkey (dst, ek);
+ }
+ }
+ if (j == 0) {
+ save_u32 (cnt);
+ write_log("%d exkeys\n", cnt);
+ }
}
write_log("END\n");
return dst;
}
+uae_u8 *save_filesys_common (int *len)
+{
+ uae_u8 *dstbak, *dst;
+ if (nr_units() == 0)
+ return NULL;
+ dstbak = dst = malloc (10000);
+ save_u32 (2);
+ save_u64 (a_uniq);
+ save_u64 (key_uniq);
+ *len = dst - dstbak;
+ return dstbak;
+}
+
+uae_u8 *restore_filesys_common (uae_u8 *src)
+{
+ if (restore_u32 () != 2)
+ return src;
+ free_mountinfo();
+ a_uniq = restore_u64 ();
+ key_uniq = restore_u64 ();
+ return src;
+}
+
uae_u8 *save_filesys (int num, int *len)
{
uae_u8 *dstbak, *dst;
UnitInfo *ui;
int type = is_hardfile (num);
- dstbak = dst = malloc (10000);
ui = &mountinfo.ui[num];
- save_u32 (1); /* version */
+ write_log("FS_FILESYS: '%s' '%s'\n", ui->devname, ui->volname);
+ dstbak = dst = malloc (10000);
+ save_u32 (2); /* version */
save_u32 (ui->devno);
save_u16 (type);
save_string (ui->rootdir);
save_u32 (filesys_configdev);
if (type == FILESYS_VIRTUAL)
dst = save_filesys_virtual (ui, dst);
+ if (type == FILESYS_HARDFILE || type == FILESYS_HARDFILE_RDB)
+ dst = save_filesys_hardfile (ui, dst);
*len = dst - dstbak;
return dstbak;
}
char *devname = 0, *volname = 0, *rootdir = 0, *filesysdir = 0;
int bootpri, readonly;
- if (restore_u32 () != 1)
+ if (restore_u32 () != 2)
return src;
devno = restore_u32 ();
type = restore_u16 ();
filesysdir = restore_string ();
bootpri = restore_u8 ();
readonly = restore_u8 ();
+ ui = &mountinfo.ui[devno];
+ ui->startup = restore_u32 ();
+ filesys_configdev = restore_u32 ();
+ if (type == FILESYS_HARDFILE || type == FILESYS_HARDFILE_RDB)
+ src = restore_filesys_hardfile(ui, src);
if (set_filesys_unit (devno, devname, volname, rootdir, readonly,
- 0, 0, 0, 0, bootpri, filesysdir[0] ? filesysdir : NULL, 0)) {
+ ui->hf.secspertrack, ui->hf.surfaces, ui->hf.reservedblocks, ui->hf.blocksize,
+ bootpri, filesysdir[0] ? filesysdir : NULL, 0) < 0) {
write_log ("filesys '%s' failed to restore\n", rootdir);
goto end;
}
- ui = &mountinfo.ui[devno];
- ui->startup = restore_u32 ();
- filesys_configdev = restore_u32 ();
if (type == FILESYS_VIRTUAL)
src = restore_filesys_virtual (ui, src);
end:
xfree (filesysdir);
return src;
}
+
+int save_filesys_cando(void)
+{
+ if (nr_units() == 0)
+ return -1;
+ return filesys_in_interrupt ? 0 : 1;
+}
* (c) 2006 Toni Wilen
*/
+#define GAYLE_LOG 0
+
#include "sysconfig.h"
#include "sysdeps.h"
DA8000 to DAFFFF 32 KB Credit Card and IDE configregisters
DB0000 to DBFFFF 64 KB Not used(reserved for external IDE)
* DC0000 to DCFFFF 64 KB Real Time Clock(RTC)
-DD0000 to DDFFFF 64 KB RESERVED for DMA controller
+DD0000 to DDFFFF 64 KB A3000 DMA controller
DE0000 to DEFFFF 64 KB Motherboard resources
*/
#define GAYLE_IRQ_IDEACK1 0x02
#define GAYLE_IRQ_IDEACK0 0x01
-#define GAYLE_LOG 0
-
static uae_u8 gayle_irq;
static void ide_interrupt(void)
dummy_lgeti, dummy_wgeti, ABFLAG_IO
};
-static void mbdmac_write (uae_u32 addr, uae_u32 val, int size)
+/* CNTR bits. */
+#define CNTR_TCEN (1<<5)
+#define CNTR_PREST (1<<4)
+#define CNTR_PDMD (1<<3)
+#define CNTR_INTEN (1<<2)
+#define CNTR_DDIR (1<<1)
+#define CNTR_IO_DX (1<<0)
+/* ISTR bits. */
+#define ISTR_INTX (1<<8)
+#define ISTR_INT_F (1<<7)
+#define ISTR_INTS (1<<6)
+#define ISTR_E_INT (1<<5)
+#define ISTR_INT_P (1<<4)
+#define ISTR_UE_INT (1<<3)
+#define ISTR_OE_INT (1<<2)
+#define ISTR_FF_FLG (1<<1)
+#define ISTR_FE_FLG (1<<0)
+
+static uae_u32 dmac_wtc, dmac_cntr, dmac_acr, dmac_istr, dmac_dawr, dmac_dma;
+static uae_u8 sasr, scmd;
+static int wdcmd_active;
+
+static void wd_cmd(uae_u8 data)
+{
+ switch (sasr)
+ {
+ case 0x15:
+ write_log("DESTINATION ID: %02.2X\n", data);
+ break;
+ case 0x18:
+ write_log("COMMAND: %02.2X\n", data);
+ wdcmd_active = 10;
+ break;
+ case 0x19:
+ write_log("DATA: %02.2X\n", data);
+ break;
+ default:
+ write_log("unsupported WD33C33A register %02.2X\n", sasr);
+ break;
+ }
+}
+
+void mbdmac_hsync(void)
+{
+ if (wdcmd_active == 0)
+ return;
+ wdcmd_active--;
+ if (wdcmd_active > 0)
+ return;
+ if (!(dmac_cntr & CNTR_INTEN)) {
+ wdcmd_active = 1;
+ return;
+ }
+ dmac_istr |= ISTR_INT_P | ISTR_E_INT | ISTR_INTS;
+}
+
+static void dmac_start_dma(void)
+{
+ dmac_istr |= ISTR_E_INT;
+}
+static void dmac_stop_dma(void)
+{
+ dmac_dma = 0;
+}
+static void dmac_cint(void)
+{
+ dmac_istr = 0;
+}
+static void dmacreg_write(uae_u32 *reg, int addr, uae_u32 val, int size)
+{
+ addr = (size - 1) - addr;
+ (*reg) &= ~(0xff << (addr * 8));
+ (*reg) |= (val & 0xff) << (addr * 8);
+}
+static uae_u32 dmacreg_read(uae_u32 val, int addr, int size)
+{
+ addr = (size - 1) - addr;
+ return (val >> (addr * 8)) & 0xff;
+}
+
+static void mbdmac_write (uae_u32 addr, uae_u32 val)
{
if (GAYLE_LOG)
- write_log ("DMAC_WRITE %08.8X=%08.8X (%d) PC=%08.8X\n", addr, val, size, M68K_GETPC);
+ write_log ("DMAC_WRITE %08.8X=%02.2X PC=%08.8X\n", addr, val & 0xff, M68K_GETPC);
+ addr &= 0xffff;
+ switch (addr)
+ {
+ case 0x02:
+ case 0x03:
+ dmacreg_write(&dmac_dawr, addr - 0x02, val, 2);
+ break;
+ case 0x04:
+ case 0x05:
+ case 0x06:
+ case 0x07:
+ dmacreg_write(&dmac_wtc, addr - 0x04, val, 4);
+ break;
+ case 0x0a:
+ case 0x0b:
+ dmacreg_write(&dmac_cntr, addr - 0x0a, val, 2);
+ break;
+ case 0x0c:
+ case 0x0d:
+ case 0x0e:
+ case 0x0f:
+ dmacreg_write(&dmac_acr, addr - 0x0c, val, 4);
+ break;
+ case 0x12:
+ case 0x13:
+ if (!dmac_dma) {
+ dmac_dma = 1;
+ dmac_start_dma();
+ }
+ break;
+ case 0x16:
+ case 0x17:
+ /* FLUSH */
+ break;
+ case 0x1a:
+ case 0x1b:
+ dmac_cint();
+ break;
+ case 0x1e:
+ case 0x1f:
+ /* ISTR */
+ break;
+ case 0x3e:
+ case 0x3f:
+ dmac_dma = 0;
+ dmac_stop_dma();
+ break;
+ case 0x49:
+ sasr = val;
+ break;
+ case 0x43:
+ wd_cmd(val);
+ break;
+ }
}
-static uae_u32 mbdmac_read (uae_u32 addr, int size)
+static uae_u32 mbdmac_read (uae_u32 addr)
{
+ uae_u32 vaddr = addr;
+ uae_u32 v = 0xffffffff;
+ addr &= 0xffff;
+ switch (addr)
+ {
+ case 0x02:
+ case 0x03:
+ v = dmacreg_read(dmac_dawr, addr - 0x02, 2);
+ break;
+ case 0x04:
+ case 0x05:
+ case 0x06:
+ case 0x07:
+ v = dmacreg_read(dmac_wtc, addr - 0x04, 4);
+ break;
+ case 0x0a:
+ case 0x0b:
+ v = dmacreg_read(dmac_cntr, addr - 0x0a, 2);
+ break;
+ case 0x0c:
+ case 0x0d:
+ case 0x0e:
+ case 0x0f:
+ v = dmacreg_read(dmac_acr, addr - 0x0c, 4);
+ break;
+ case 0x12:
+ case 0x13:
+ if (dmac_dma) {
+ dmac_dma = 1;
+ dmac_start_dma();
+ }
+ v = 0;
+ break;
+ case 0x1a:
+ case 0x1b:
+ dmac_cint();
+ v = 0;
+ break;;
+ case 0x1e:
+ case 0x1f:
+ v = dmacreg_read(dmac_istr, addr - 0x1e, 2);
+ break;
+ case 0x3e:
+ case 0x3f:
+ dmac_dma = 0;
+ dmac_stop_dma();
+ v = 0;
+ break;
+ case 0x49:
+ v = sasr;
+ break;
+ case 0x43:
+ v = scmd;
+ break;
+ }
if (GAYLE_LOG)
- write_log ("DMAC_READ %08.8X\n", addr);
- return 0xff;
+ write_log ("DMAC_READ %08.8X=%02.2X PC=%X\n", vaddr, v & 0xff, M68K_GETPC);
+ return v;
}
static uae_u32 REGPARAM3 mbdmac_lget (uaecptr) REGPARAM;
uae_u32 REGPARAM2 mbdmac_lget (uaecptr addr)
{
- addr &= 0xFFFF;
- return (uae_u32)(mbdmac_wget (addr) << 16) + mbdmac_wget (addr + 2);
+ return (mbdmac_wget (addr) << 16) | mbdmac_wget (addr + 2);
}
uae_u32 REGPARAM2 mbdmac_wget (uaecptr addr)
{
- return mbdmac_read (addr, 2);
+ return (mbdmac_bget (addr) << 8) | mbdmac_bget(addr + 1);;
}
uae_u32 REGPARAM2 mbdmac_bget (uaecptr addr)
{
- return mbdmac_read (addr, 1);
+ return mbdmac_read (addr);
}
void REGPARAM2 mbdmac_lput (uaecptr addr, uae_u32 value)
void REGPARAM2 mbdmac_wput (uaecptr addr, uae_u32 value)
{
- mbdmac_write (addr, value, 2);
+ mbdmac_bput (addr, value);
+ mbdmac_bput (addr, value + 1);
}
void REGPARAM2 mbdmac_bput (uaecptr addr, uae_u32 value)
{
- mbdmac_write (addr, value, 1);
+ mbdmac_write (addr, value);
}
addrbank mbdmac_bank = {
mbdmac_lget, mbdmac_wget, mbdmac_bget,
mbdmac_lput, mbdmac_wput, mbdmac_bput,
- default_xlate, default_check, NULL, "DMAC",
+ default_xlate, default_check, NULL, "A3000 DMAC",
dummy_lgeti, dummy_wgeti, ABFLAG_IO
};
uae_thread_id tid;
int thread_running;
uae_sem_t sync_sem;
- int opencount;
+ uaecptr base;
};
static uae_sem_t change_sem;
}
static void *hardfile_thread (void *devs);
-static int start_thread (int unit)
+static int start_thread (TrapContext *context, int unit)
{
struct hardfileprivdata *hfpd = &hardfpd[unit];
if (hfpd->thread_running)
return 1;
memset (hfpd, 0, sizeof (struct hardfileprivdata));
+ hfpd->base = m68k_areg(&context->regs, 6);
init_comm_pipe (&hfpd->requests, 100, 1);
uae_sem_init (&hfpd->sync_sem, 0, 0);
uae_start_thread ("hardfile", hardfile_thread, hfpd, &hfpd->tid);
int err = -1;
/* Check unit number */
- if (unit >= 0 && get_hardfile_data (unit) && start_thread (unit)) {
- hfpd->opencount++;
- put_word (m68k_areg(&context->regs, 6) + 32, get_word (m68k_areg(&context->regs, 6) + 32) + 1);
+ if (unit >= 0 && get_hardfile_data (unit) && start_thread (context, unit)) {
+ put_word (hfpd->base + 32, get_word (hfpd->base + 32) + 1);
put_long (tmp1 + 24, unit); /* io_Unit */
put_byte (tmp1 + 31, 0); /* io_Error */
put_byte (tmp1 + 8, 7); /* ln_type = NT_REPLYMSG */
int unit = mangleunit (get_long (request + 24));
struct hardfileprivdata *hfpd = &hardfpd[unit];
- if (!hfpd->opencount)
+ if (!hfpd)
return 0;
- hfpd->opencount--;
- if (hfpd->opencount == 0)
+ put_word (hfpd->base + 32, get_word (hfpd->base + 32) - 1);
+ if (get_word(hfpd->base + 32) == 0)
write_comm_pipe_u32 (&hfpd->requests, 0, 1);
- put_word (m68k_areg(&context->regs, 6) + 32, get_word (m68k_areg(&context->regs, 6) + 32) - 1);
return 0;
}
struct hardfileprivdata *hfpd = &hardfpd[unit];
hf_log2 ("uaehf.device abortio ");
- if (!hfd) {
+ start_thread(context, unit);
+ if (!hfd || !hfpd || !hfpd->thread_running) {
put_byte (request + 31, 32);
hf_log2 ("error\n");
return get_byte (request + 31);
struct hardfileprivdata *hfpd = &hardfpd[unit];
put_byte (request + 8, NT_MESSAGE);
- if (!hfd) {
+ start_thread(context, unit);
+ if (!hfd || !hfpd || !hfpd->thread_running) {
put_byte (request + 31, 32);
return get_byte (request + 31);
}
for (i = 0; i < MAX_FILESYSTEM_UNITS; i++) {
hfpd = &hardfpd[i];
- if (hfpd->opencount > 0) {
+ if (hfpd->base && get_word(hfpd->base + 32) > 0) {
for (j = 0; j < MAX_ASYNC_REQUESTS; j++) {
uaecptr request;
if ((request = hfpd->d_request[i]))
void gayle_reset(int);
+void mbdmac_hsync(void);
extern int ersatzkickfile;
extern int cloanto_rom;
extern uae_u16 kickstart_version;
-extern int uae_boot_rom;
+extern int uae_boot_rom, uae_boot_rom_size;
extern uae_u8* baseaddr[];
extern uae_u8 *restore_filesys (uae_u8 *src);
extern uae_u8 *save_filesys (int num, int *len);
+extern uae_u8 *restore_filesys_common (uae_u8 *src);
+extern uae_u8 *save_filesys_common (int *len);
+extern int save_filesys_cando(void);
extern void restore_cram (int, size_t);
extern void restore_bram (int, size_t);
extern void restore_fram (int, size_t);
extern void restore_zram (int, size_t);
+extern void restore_bootrom (int, size_t);
extern void restore_pram (int, size_t);
extern void restore_a3000lram (int, size_t);
extern void restore_a3000hram (int, size_t);
extern uae_u8 *save_bram (int *);
extern uae_u8 *save_fram (int *);
extern uae_u8 *save_zram (int *);
+extern uae_u8 *save_bootrom (int *);
extern uae_u8 *save_pram (int *);
extern uae_u8 *save_a3000lram (int *);
extern uae_u8 *save_a3000hram (int *);
extern uae_u8 *save_hrtmon (int *, uae_u8 *);
extern void savestate_initsave (char *filename, int docompress);
-extern void save_state (char *filename, char *description);
+extern int save_state (char *filename, char *description);
extern void restore_state (char *filename);
extern void savestate_restore_finish (void);
uae_u32 max_z3fastmem = 512 * 1024 * 1024;
#endif
-static size_t chip_filepos, bogo_filepos, rom_filepos, a3000lmem_filepos, a3000hmem_filepos;
+static size_t bootrom_filepos, chip_filepos, bogo_filepos, rom_filepos, a3000lmem_filepos, a3000hmem_filepos;
static struct romlist *rl;
static int romlist_cnt;
cdtv_loadcardmem(cardmemory, allocated_cardmem);
}
if (savestate_state == STATE_RESTORE) {
+ restore_ram (bootrom_filepos, rtarea);
restore_ram (chip_filepos, chipmemory);
if (allocated_bogomem > 0)
restore_ram (bogo_filepos, bogomemory);
if ((cloanto_rom || currprefs.cs_ksmirror) && !currprefs.maprom && !extendedkickmem_type)
map_banks (&kickmem_bank, 0xE0, 8, 0);
if (currprefs.cs_ksmirror == 2) { /* unexpanded A1200 also maps ROM here.. */
- map_banks (&kickmem_bank, 0xA8, 8, 0);
- map_banks (&kickmem_bank, 0xB0, 8, 0);
+ if (!currprefs.cart_internal) {
+ map_banks (&kickmem_bank, 0xA8, 8, 0);
+ map_banks (&kickmem_bank, 0xB0, 8, 0);
+ }
}
#ifdef ARCADIA
if (is_arcadia_rom (currprefs.romextfile) == ARCADIA_BIOS) {
void memory_hardreset(void)
{
+ if (savestate_state == STATE_RESTORE)
+ return;
if (chipmemory)
memset (chipmemory, 0, allocated_chipmem);
if (bogomemory)
/* memory save/restore code */
+uae_u8 *save_bootrom(int *len)
+{
+ if (!uae_boot_rom)
+ return 0;
+ *len = uae_boot_rom_size;
+ return rtarea;
+}
+
uae_u8 *save_cram (int *len)
{
*len = allocated_chipmem;
return a3000hmemory;
}
+void restore_bootrom (int len, size_t filepos)
+{
+ bootrom_filepos = filepos;
+}
+
void restore_cram (int len, size_t filepos)
{
chip_filepos = filepos;
extern uae_u32 get_fpsr(void);
#define COUNT_INSTRS 0
-#define MC68060_PCR 0x04300100
+#define MC68060_PCR 0x04300100
#define MC68EC060_PCR 0x04310100
#if COUNT_INSTRS
}
#endif
+static uae_u32 caar, cacr, itt0, itt1, dtt0, dtt1, tcr, mmusr, urp, srp, buscr;
+
+static void set_cpu_caches(void)
+{
+#ifdef JIT
+ if (currprefs.cpu_model < 68040) {
+ set_cache_state(cacr & 1);
+ if (cacr & 0x08)
+ flush_icache(1);
+ } else {
+ set_cache_state(cacr & 0x8000);
+ }
+#endif
+}
+
STATIC_INLINE void count_instr (unsigned int opcode)
{
}
}
}
+static void prefs_changed_cpu (void)
+{
+ fixup_cpu (&changed_prefs);
+ currprefs.cpu_level = changed_prefs.cpu_level;
+ currprefs.cpu_model = changed_prefs.cpu_model;
+ currprefs.fpu_model = changed_prefs.fpu_model;
+ currprefs.cpu_compatible = changed_prefs.cpu_compatible;
+ currprefs.cpu_cycle_exact = changed_prefs.cpu_cycle_exact;
+ currprefs.blitter_cycle_exact = changed_prefs.cpu_cycle_exact;
+}
+
void check_prefs_changed_cpu (void)
{
if (currprefs.cpu_model != changed_prefs.cpu_model
|| currprefs.cpu_compatible != changed_prefs.cpu_compatible
|| currprefs.cpu_cycle_exact != changed_prefs.cpu_cycle_exact) {
- fixup_cpu (&changed_prefs);
- currprefs.cpu_level = changed_prefs.cpu_level;
- currprefs.cpu_model = changed_prefs.cpu_model;
- currprefs.fpu_model = changed_prefs.fpu_model;
- currprefs.cpu_compatible = changed_prefs.cpu_compatible;
- currprefs.cpu_cycle_exact = changed_prefs.cpu_cycle_exact;
- currprefs.blitter_cycle_exact = changed_prefs.cpu_cycle_exact;
+ prefs_changed_cpu ();
if (!currprefs.cpu_compatible && changed_prefs.cpu_compatible)
fill_prefetch_slow (®s);
build_cpufunctbl ();
{
int i;
- fixup_cpu (&changed_prefs);
- fixup_cpu (&currprefs);
+ prefs_changed_cpu ();
update_68k_cycles ();
for (i = 0 ; i < 256 ; i++) {
/* We need to check whether NATMEM settings have changed
* before starting the CPU */
check_prefs_changed_comp ();
+ set_cpu_caches();
#endif
}
#if 0
if (1 || nr < 24)
write_log ("exception %d %08.8X %08.8X (%04.4X %04.4X)\n",
- nr, oldpc, m68k_getpc(), intena, intreq);
+ nr, oldpc, m68k_getpc(regs), intena, intreq);
#endif
#ifdef CPUEMU_12
if (currprefs.cpu_cycle_exact && currprefs.cpu_model == 68000)
do_interrupt (nr, ®s);
}
-static uae_u32 caar, cacr, itt0, itt1, dtt0, dtt1, tcr, mmusr, urp, srp, buscr;
-
#ifndef CPUEMU_68000_ONLY
static int movec_illg (int regno)
else if (currprefs.cpu_model == 68060)
cacr_mask = 0xf880e000;
cacr = *regp & cacr_mask;
-#ifdef JIT
- if (currprefs.cpu_model < 68040) {
- set_cache_state(cacr & 1);
- if (*regp & 0x08) {
- flush_icache(1);
- }
- } else {
- set_cache_state((cacr & 0x8000) || 0);
- if (*regp & 0x08) { /* Just to be on the safe side */
- flush_icache(2);
- }
- }
-#endif
+ set_cpu_caches();
}
break;
/* 68040/060 only */
regs.vbr = regs.sfc = regs.dfc = 0;
#ifdef FPUEMU
regs.fpcr = regs.fpsr = regs.fpiar = 0;
- regs.fp_result=1;
+ regs.fp_result = 1;
regs.irc = 0xffff;
#endif
caar = cacr = 0;
m68k_setpc (®s, m68k_getpc (®s));
fill_prefetch_slow (®s);
opcode = get_word (regs.pc);
- if (opcode == 0x4e72 /* RTE */
+ if (opcode == 0x4e72 /* RTE */
|| opcode == 0x4e74 /* RTD */
|| opcode == 0x4e75 /* RTS */
|| opcode == 0x4e77 /* RTR */
|| opcode == 0x4e76 /* TRAPV */
|| (opcode & 0xffc0) == 0x4e80 /* JSR */
|| (opcode & 0xffc0) == 0x4ec0 /* JMP */
- || (opcode & 0xff00) == 0x6100 /* BSR */
+ || (opcode & 0xff00) == 0x6100 /* BSR */
|| ((opcode & 0xf000) == 0x6000 /* Bcc */
&& cctrue(®s.ccrflags, (opcode >> 8) & 0xf))
- || ((opcode & 0xf0f0) == 0x5050 /* DBcc */
+ || ((opcode & 0xf0f0) == 0x5050 /* DBcc */
&& !cctrue(®s.ccrflags, (opcode >> 8) & 0xf)
&& (uae_s16)m68k_dreg(®s, opcode & 7) != 0))
{
total_cycles += cpu_cycles;
pc_hist[blocklen].specmem = special_mem;
blocklen++;
- if (end_block(opcode) || blocklen >= MAXRUN || r->spcflags || uae_int_requested) { // || bsd_int_requested) {
+ if (end_block(opcode) || blocklen >= MAXRUN || r->spcflags || uae_int_requested) {
compile_block(pc_hist,blocklen,total_cycles);
return; /* We will deal with the spcflags in the caller */
}
if (savestate_state == STATE_RESTORE || savestate_state == STATE_REWIND) {
map_overlay (1);
fill_prefetch_slow (®s); /* compatibility with old state saves */
+ memory_map_dump();
}
savestate_restore_finish ();
#endif
{
init_m68k ();
m68k_setpc (®s, regs.pc);
+ set_cpu_caches();
}
uae_u8 *save_cpu (int *len, uae_u8 *dstptr)
#include "zfile.h"
#include "threaddep/thread.h"
#include "serial.h"
+#include "savestate.h"
#include <Ghostscript/errors.h>
#include <Ghostscript/iapi.h>
}
static uae_u32 p2ctab[256][2];
-static int set_gc_called = 0;
+static int set_gc_called = 0, init_picasso_screen_called = 0;
//fastscreen
static uaecptr oldscr = 0;
#ifdef _DEBUG
palette_changed = 0;
}
- if (vsyncgfxwrite==1) {
+ if (vsyncgfxwrite == 1) {
static long blitcount;
vsyncgfxcount++;
- if (vsyncgfxcount>1) {
+ if (vsyncgfxcount > 1) {
if (picasso_on) {
if (picasso96_state.RGBFormat == picasso_vidinfo.rgbformat
|| picasso96_state.RGBFormat == RGBFB_CHUNKY) {
struct RenderInfo ri;
static int beamcon0_before, p96refresh_was;
- if (! picasso_on)return;
+ if (! picasso_on)
+ return;
{ //for higher P96 mousedraw rate
/* HACK */
extern uae_u16 vtotal;
if (p96hack_vpos2) {
- vtotal=p96hack_vpos2;
+ vtotal = p96hack_vpos2;
beamcon0_before = new_beamcon0;
new_beamcon0 |= 0x80;
p96refresh_active = 1;
return !flag;
}
+
+static void init_picasso_screen(void);
void picasso_enablescreen (int on)
{
+ if (!init_picasso_screen_called)
+ init_picasso_screen();
wgfx_linestart = 0xFFFFFFFF;
picasso_refresh (1);
write_log ("SetSwitch() from threadid %d - showing %s screen\n", GetCurrentThreadId(), on ? "picasso96": "amiga");
}
-static void init_picasso_screen( void )
+static void init_picasso_screen(void)
{
- if(set_panning_called)
- {
+ if(set_panning_called) {
picasso96_state.Extent = picasso96_state.Address + picasso96_state.BytesPerRow * picasso96_state.VirtualHeight;
}
- if (set_gc_called)
- {
+ if (set_gc_called) {
gfx_set_picasso_modeinfo (picasso96_state.Width, picasso96_state.Height,
picasso96_state.GC_Depth, picasso96_state.RGBFormat);
}
DX_SetPalette (0, 256);
picasso_refresh (1);
}
+ init_picasso_screen_called = 1;
}
/*
* because SetSwitch() is not called for subsequent Picasso screens.
*/
+static void picasso_SetPanningInit(void)
+{
+ picasso96_state.XYOffset = picasso96_state.Address + (picasso96_state.XOffset * picasso96_state.BytesPerPixel)
+ + (picasso96_state.YOffset * picasso96_state.BytesPerRow);
+ if((picasso96_state.VirtualWidth > picasso96_state.Width) || (picasso96_state.VirtualHeight > picasso96_state.Height))
+ picasso96_state.BigAssBitmap = 1;
+ else
+ picasso96_state.BigAssBitmap = 0;
+ picasso96_state.BytesPerRow = picasso96_state.VirtualWidth * picasso96_state.BytesPerPixel;
+}
+
uae_u32 REGPARAM2 picasso_SetPanning (struct regstruct *regs)
{
uae_u16 Width = m68k_dreg (regs, 0);
uaecptr start_of_screen = m68k_areg (regs, 1);
uaecptr bi = m68k_areg(regs, 0);
- uaecptr bmeptr = get_long( bi + PSSO_BoardInfo_BitMapExtra ); /* Get our BoardInfo ptr's BitMapExtra ptr */
+ uaecptr bmeptr = get_long(bi + PSSO_BoardInfo_BitMapExtra); /* Get our BoardInfo ptr's BitMapExtra ptr */
uae_u16 bme_width, bme_height;
if(oldscr == 0) {
oldscr = start_of_screen;
}
- bme_width = get_word( bmeptr + PSSO_BitMapExtra_Width );
- bme_height = get_word( bmeptr + PSSO_BitMapExtra_Height );
+ bme_width = get_word(bmeptr + PSSO_BitMapExtra_Width);
+ bme_height = get_word(bmeptr + PSSO_BitMapExtra_Height);
picasso96_state.Address = start_of_screen; /* Amiga-side address */
picasso96_state.XOffset = (uae_s16)(m68k_dreg (regs, 1) & 0xFFFF);
picasso96_state.YOffset = (uae_s16)(m68k_dreg (regs, 2) & 0xFFFF);
- picasso96_state.XYOffset = picasso96_state.Address + (picasso96_state.XOffset * picasso96_state.BytesPerPixel)
- + (picasso96_state.YOffset * picasso96_state.BytesPerRow);
picasso96_state.VirtualWidth = bme_width;
picasso96_state.VirtualHeight = bme_height;
- if((bme_width > Width) || (bme_height > picasso96_state.Height))
- picasso96_state.BigAssBitmap = 1;
- else
- picasso96_state.BigAssBitmap = 0;
picasso96_state.RGBFormat = m68k_dreg (regs, 7);
picasso96_state.BytesPerPixel = GetBytesPerPixel (picasso96_state.RGBFormat);
- picasso96_state.BytesPerRow = bme_width * picasso96_state.BytesPerPixel;
-
+ picasso_SetPanningInit();
+
set_panning_called = 1;
P96TRACE(("SetPanning(%d, %d, %d) Start 0x%x, BPR %d Bpp %d RGBF %d\n",
Width, picasso96_state.XOffset, picasso96_state.YOffset,
uae_u8 *restore_p96 (uae_u8 *src)
{
+ uae_u32 flags;
+ if (restore_u32 () != 1)
+ return src;
+ InitPicasso96();
+ flags = restore_u32();
+ picasso_requested_on = !!(flags & 1);
+ picasso96_state.SwitchState = picasso_requested_on;
+ picasso_on = 0;
+ init_picasso_screen_called = 0;
+ set_gc_called = !!(flags & 2);
+ set_panning_called = !!(flags & 4);
+ changed_prefs.gfxmem_size = restore_u32();
+ picasso96_state.Address = restore_u32();
+ picasso96_state.RGBFormat = restore_u32();
+ picasso96_state.Width = restore_u16();
+ picasso96_state.Height = restore_u16();
+ picasso96_state.VirtualWidth = restore_u16();
+ picasso96_state.VirtualHeight = restore_u16();
+ picasso96_state.XOffset = restore_u16();
+ picasso96_state.YOffset = restore_u16();
+ picasso96_state.GC_Depth = restore_u8();
+ picasso96_state.GC_Flags = restore_u8();
+ picasso96_state.BytesPerRow = restore_u16();
+ picasso96_state.BytesPerPixel = restore_u8();
+ picasso96_state.HostAddress = NULL;
+ picasso_SetPanningInit();
+ picasso96_state.Extent = picasso96_state.Address + picasso96_state.BytesPerRow * picasso96_state.VirtualHeight;
+ if (set_gc_called) {
+ init_picasso_screen ();
+ init_hz_p96 ();
+ }
return src;
}
uae_u8 *save_p96 (int *len, uae_u8 *dstptr)
{
- uae_u8 *dstbak,*dst;
+ uae_u8 *dstbak, *dst;
- //dstbak = dst = malloc (16 + 12 + 1 + 1);
- return 0;
+ if (currprefs.gfxmem_size == 0)
+ return NULL;
+ if (dstptr)
+ dstbak = dst = dstptr;
+ else
+ dstbak = dst = malloc (1000);
+ save_u32 (1);
+ save_u32 ((picasso_on ? 1 : 0) | (set_gc_called ? 2 : 0) | (set_panning_called ? 4 : 0));
+ save_u32 (currprefs.gfxmem_size);
+ save_u32 (picasso96_state.Address);
+ save_u32 (picasso96_state.RGBFormat);
+ save_u16 (picasso96_state.Width);
+ save_u16 (picasso96_state.Height);
+ save_u16 (picasso96_state.VirtualWidth);
+ save_u16 (picasso96_state.VirtualHeight);
+ save_u16 (picasso96_state.XOffset);
+ save_u16 (picasso96_state.YOffset);
+ save_u8 (picasso96_state.GC_Depth);
+ save_u8 (picasso96_state.GC_Flags);
+ save_u16 (picasso96_state.BytesPerRow);
+ save_u8 (picasso96_state.BytesPerPixel);
+ *len = dst - dstbak;
+ return dstbak;
}
#endif
CONTROL "68060",IDC_CPU5,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,13,85,66,10
CONTROL "More compatible [] Emulate 68000's prefetch registers. More compatible but slower.",IDC_COMPATIBLE,
"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,10,114,73,8
- CONTROL "JIT [] Enable just-in-time CPU emulator. Significantly increases the speed of the CPU emulation. Requires 68020 or 68040 CPU.",IDC_JITENABLE,
+ CONTROL "JIT [] Enable just-in-time CPU emulator. Significantly increases the speed of the CPU emulation. Requires 68020 or higher CPU.",IDC_JITENABLE,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,127,73,10
GROUPBOX "CPU Emulation Speed",IDC_STATIC,90,3,205,90
CONTROL "Fastest possible, but maintain chipset timing",IDC_CS_HOST,
RTEXT "Cache size:",IDC_CS_CACHE_TEXT,95,113,45,10,SS_CENTERIMAGE | WS_TABSTOP
CONTROL "Slider1",IDC_CACHE,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,140,108,115,20
EDITTEXT IDC_CACHETEXT,255,113,30,12,ES_CENTER | ES_READONLY
- CONTROL "Hard flush",IDC_HARDFLUSH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,100,141,60,10
- CONTROL "Constant jump",IDC_CONSTJUMP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,100,155,60,10
- CONTROL "FPU support",IDC_JITFPU,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,100,168,60,10
- CONTROL "Force settings",IDC_FORCE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,165,141,61,10
- CONTROL "No flags",IDC_NOFLAGS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,165,155,60,10
- CONTROL "Direct",IDC_TRUST0,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,230,141,34,10
- CONTROL "Indirect",IDC_TRUST1,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,230,155,45,10
- CONTROL "After RTG",IDC_TRUST2,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,230,168,59,10
+ CONTROL "Hard flush",IDC_HARDFLUSH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,100,141,63,10
+ CONTROL "Constant jump",IDC_CONSTJUMP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,100,155,63,10
+ CONTROL "FPU support",IDC_JITFPU,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,100,168,62,10
+ CONTROL "Force settings",IDC_FORCE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,168,141,62,10
+ CONTROL "No flags",IDC_NOFLAGS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,168,155,62,10
+ CONTROL "Direct",IDC_TRUST0,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,235,141,52,10
+ CONTROL "Indirect",IDC_TRUST1,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,235,155,52,10
+ CONTROL "After RTG",IDC_TRUST2,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,235,168,52,10
CONTROL "More compatible [] More compatible but slower FPU emulation.",IDC_COMPATIBLE_FPU,
"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,9,206,73,10
GROUPBOX "FPU",IDC_STATIC,6,144,81,76,BS_LEFT
IDS_NUMSG_MODRIP_NOTFOUND "No music modules or packed data found."
IDS_NUMSG_MODRIP_FINISHED "Scan finished."
IDS_NUMSG_MODRIP_SAVE "Module/packed data found\n%s\nWould you like to save it?"
- IDS_NUMSG_KS68020 "The selected system ROM requires a 68020 or higher CPU."
+ IDS_NUMSG_KS68020 "The selected system ROM requires a 68020 with 32-bit addressing or 68030 or higher CPU."
IDS_NUMSG_ROMNEED "One of the following system ROMs is required:\n\n%s\n\nCheck the System ROM path in the Paths panel and click Rescan ROMs."
- IDS_NUMSG_STATEHD "WARNING: State saves do not support hard drive emulation. This message will not appear again."
+ IDS_NUMSG_STATEHD "WARNING: Current configuration is not compatible with state saves. This message will not appear again."
IDS_NUMSG_NOCAPS "Selected disk image needs the SPS plugin\nwhich is available from\nhttp//www.softpres.org/"
IDS_NUMSG_OLDCAPS "You need an updated SPS plugin\nwhich is available from\nhttp//www.softpres.org/"
IDS_IMGCHK_BOOTBLOCKCRCERROR
IDS_ROM_UNAVAILABLE "unavailable"
IDS_HARDDRIVESAFETYWARNING
"Warning: The safety test has been disabled, and non-empty hard disks were detected.\n\nHard disks marked with 'HD_*_' are not empty."
- IDS_NUMSG_KS68EC020 "The selected system ROM requires a 68EC020 or higher CPU."
+ IDS_NUMSG_KS68EC020 "The selected system ROM requires a 68020 with 24-bit addressing or higher CPU."
IDS_ROMSCANNOROMS "No supported system ROMs detected."
IDS_NUMSG_KICKREP "You need to have a floppy disk (image file) in DF0: to use the system ROM replacement."
IDS_NUMSG_KICKREPNO "The floppy disk (image file) in DF0: is not compatible with the system ROM replacement functionality."
#define GETBDM(x) (((x) - ((x / 10000) * 10000)) / 100)
#define GETBDD(x) ((x) % 100)
-#define WINUAEBETA 3
+#define WINUAEBETA 4
#define WINUAEPUBLICBETA 1
-#define WINUAEDATE MAKEBD(2007, 3, 31)
+#define WINUAEDATE MAKEBD(2007, 4, 6)
#define IHF_WINDOWHIDDEN 6
#define NORMAL_WINDOW_STYLE (WS_VISIBLE | WS_BORDER | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU)
static void values_from_cpudlg (HWND hDlg)
{
int newcpu, newfpu, newtrust, oldcache, jitena;
- static int cachesize_prev;
+ static int cachesize_prev, comptrust_prev, compforce_prev;
workprefs.cpu_compatible = workprefs.cpu_cycle_exact | (IsDlgButtonChecked (hDlg, IDC_COMPATIBLE) ? 1 : 0);
workprefs.fpu_strict = IsDlgButtonChecked (hDlg, IDC_COMPATIBLE_FPU) ? 1 : 0;
workprefs.cachesize = SendMessage(GetDlgItem(hDlg, IDC_CACHE), TBM_GETPOS, 0, 0) * 1024;
if (!jitena) {
cachesize_prev = workprefs.cachesize;
+ comptrust_prev = workprefs.comptrustbyte;
+ compforce_prev = workprefs.compforcesettings;
workprefs.cachesize = 0;
} else if (jitena && !oldcache) {
workprefs.cachesize = 8192;
- if (cachesize_prev)
+ if (cachesize_prev) {
workprefs.cachesize = cachesize_prev;
+ workprefs.comptrustbyte = comptrust_prev;
+ workprefs.comptrustword = comptrust_prev;
+ workprefs.comptrustlong = comptrust_prev;
+ workprefs.comptrustnaddr = comptrust_prev;
+ workprefs.compforcesettings = compforce_prev;
+ }
}
if (oldcache == 0 && workprefs.cachesize > 0)
canbang = 1;
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
+#include <Wingdi.h>
#include <winspool.h>
#include <winuser.h>
#include <mmsystem.h>
/* WORD extraCount; */
} DLGITEMTEMPLATEEX;
-static wchar_t font_vista[] = L"Segoe UI";
-static wchar_t font_xp[] = L"Tahoma";
-static wchar_t font_old[] = L"MS Sans Serif";
+static int fontsdetected, font_vista_ok, font_xp_ok;
+static wchar_t wfont_vista[] = L"Segoe UI";
+static wchar_t wfont_xp[] = L"Tahoma";
+static wchar_t wfont_old[] = L"MS Sans Serif";
+static char font_vista[] = "Segoe UI";
+static char font_xp[] = "Tahoma";
static BYTE *skiptext(BYTE *s)
{
wchar_t *p = NULL;
- if (os_vista)
- p = font_vista;
- else if (os_winnt)
- p = font_xp;
- if (p && !wcscmp (d2->typeface, font_old))
+ if (font_vista_ok)
+ p = wfont_vista;
+ else if (font_xp_ok)
+ p = wfont_xp;
+ if (p && !wcscmp (d2->typeface, wfont_old))
wcscpy (d2->typeface, p);
}
xfree (ns);
}
+static int CALLBACK effproc(const void *elfe, const void *ntme, DWORD type, LPARAM lParam)
+{
+ *(int*)lParam = 1;
+ return 0;
+}
+
+static void detectfonts(void)
+{
+ LOGFONT lf;
+ HDC hdc;
+
+ if (fontsdetected)
+ return;
+ memset(&lf, 0, sizeof lf);
+ hdc = GetDC(NULL);
+ if (hdc) {
+ lf.lfCharSet = DEFAULT_CHARSET;
+ lf.lfPitchAndFamily = FIXED_PITCH | VARIABLE_PITCH | FF_DONTCARE;
+ strcpy(lf.lfFaceName, font_vista);
+ EnumFontFamiliesEx(hdc, &lf, effproc, (LPARAM)&font_vista_ok, 0);
+ strcpy(lf.lfFaceName, font_xp);
+ EnumFontFamiliesEx(hdc, &lf, effproc, (LPARAM)&font_xp_ok, 0);
+ ReleaseDC(NULL, hdc);
+ }
+ if (os_vista)
+ font_vista_ok = 1;
+ if (os_winnt)
+ font_xp_ok = 1;
+ fontsdetected = 1;
+}
+
void scaleresource_setmaxsize(int w, int h)
{
+ detectfonts();
max_w = w;
max_h = h;
mult = 100;
+Beta 4:
+
+- statefiles with autoconfigurable (fast and z3fast) memory wasn't
+ restored properly
+- directory filesystem statefile support.
+- Picasso96 statefile support (not very compatible yet)
+- HDF statefile support. WARNING: HDF _WILL_ get CORRUPTED if you
+ try to restore same HDF statefiles multiple times and there has been
+ one or more writes between restores. Read-only will be forced before
+ official release.
+- JIT slowdown after restore fixed (CPU CACR register instruction cache
+ setting syncronized with JIT cache settings)
+
+ Filesystem statefile information:
+
+ Handling of missing files or directories during restore:
+ - missing root directory: most likely crashes
+ - open file:
+ dummy file with exact same name and size will be created (filled
+ with zeros) to prevent crashes. Of course application using the
+ file most likely fails because it may not contain data it expects
+ but at least FS emulation and AmigaDOS is happy..
+ - open lock:
+ lock is re-created but missing file/directory stays missing. Again,
+ filesystem and AmigaDOS is happy. Application may crash or return
+ weird errors..
+
+ Always check the log first if there are problems.
+
+ NOTE: uaescsi, bsdsocket etc.. are not saved. You may be able to
+ restore statefile with unsupported "expansion" devices enabled
+ without crashing (for example restored uaescsi won't crash the
+ emulator but Amiga-side program can get confused.. Tested with
+ AmiKit, no crashes but CD0: stops working)
+
+ NOTE2: statefile format can and will change in future betas.
+
+ Manual loading of configuration recommended before restoring.
+
+
Beta 3:
- CPU/FPU on the fly change fixes
#include "uae.h"
#include "gui.h"
#include "audio.h"
+#include "filesys.h"
int savestate_state = 0;
char savestate_fname[MAX_DPATH];
static struct staterecord staterecords[MAX_STATERECORDS];
+static void state_incompatible_warn(void)
+{
+ static int warned;
+ int dowarn = 0;
+ int i;
+
+#ifdef BSDSOCKET
+ if (currprefs.socket_emu)
+ dowarn = 1;
+#endif
+#ifdef UAESERIAL
+ if (currprefs.uaeserial)
+ dowarn = 1;
+#endif
+#ifdef SCSIEMU
+ if (currprefs.scsi)
+ dowarn = 1;
+#endif
+#ifdef CATWEASEL
+ if (currprefs.catweasel)
+ dowarn = 1;
+#endif
+#ifdef FILESYS
+ for(i = 0; i < currprefs.mountitems; i++) {
+ struct mountedinfo mi;
+ int type = get_filesys_unitconfig (&currprefs, i, &mi);
+ if (type != FILESYS_VIRTUAL)
+ dowarn = 1;
+ }
+#endif
+ if (!warned && dowarn) {
+ warned = 1;
+ notify_user (NUMSG_STATEHD);
+ }
+}
+
/* functions for reading/writing bytes, shorts and longs in big-endian
* format independent of host machine's endianess */
} else if (!strcmp (name, "ZRAM")) {
restore_zram (totallen, filepos);
continue;
+ } else if (!strcmp (name, "BORO")) {
+ restore_bootrom (totallen, filepos);
+ continue;
#endif
#ifdef PICASSO96
} else if (!strcmp (name, "PRAM")) {
#ifdef FILESYS
else if (!strcmp (name, "FSYS"))
end = restore_filesys (chunk);
+ else if (!strcmp (name, "FSYC"))
+ end = restore_filesys_common (chunk);
#endif
else
write_log ("unknown chunk '%s' size %d bytes\n", name, len);
save_chunk (f, dst, len, "FRAM", comp);
dst = save_zram (&len);
save_chunk (f, dst, len, "ZRAM", comp);
+ dst = save_bootrom (&len);
+ save_chunk (f, dst, len, "BORO", comp);
#endif
#ifdef PICASSO96
+ dst = save_p96 (&len, 0);
+ save_chunk (f, dst, len, "P96 ", 0);
dst = save_pram (&len);
save_chunk (f, dst, len, "PRAM", comp);
- dst = save_p96 (&len, 0);
- save_chunk (f, dst, len, "P96 ", comp);
#endif
}
/* Save all subsystems */
-void save_state (char *filename, char *description)
+int save_state (char *filename, char *description)
{
uae_u8 header[1000];
char tmp[100];
int len,i;
char name[5];
int comp = savestate_docompress;
- static int warned;
-#ifdef FILESYS
- if (nr_units () && !warned) {
- warned = 1;
- notify_user (NUMSG_STATEHD);
+ if (!savestate_specialdump) {
+ state_incompatible_warn();
+ if (!save_filesys_cando()) {
+ gui_message("Filesystem active. Try again later");
+ return -1;
+ }
}
-#endif
-
custom_prepare_savestate ();
-
f = zfile_fopen (filename, "w+b");
if (!f)
- return;
+ return 0;
if (savestate_specialdump) {
size_t pos;
if (savestate_specialdump == 2)
xfree(tmp);
}
zfile_fclose (f);
- return;
+ return 1;
}
dst = header;
save_chunk (f, dst, len, "HRTM", 0);
#endif
#ifdef FILESYS
- for (i = 0; i < nr_units (); i++) {
- dst = save_filesys (i, &len);
- if (dst) {
- save_chunk (f, dst, len, "FSYS", 0);
- xfree (dst);
+ dst = save_filesys_common (&len);
+ if (dst) {
+ save_chunk (f, dst, len, "FSYC", 0);
+ for (i = 0; i < nr_units (); i++) {
+ dst = save_filesys (i, &len);
+ if (dst) {
+ save_chunk (f, dst, len, "FSYS", 0);
+ xfree (dst);
+ }
}
}
#endif
write_log ("Save of '%s' complete\n", filename);
zfile_fclose (f);
savestate_state = 0;
+ return 1;
}
void savestate_quick (int slot, int save)
uae_u8 flags = get_byte (request + 30);
int command = get_word (request + 28);
struct priv_devstruct *pdev = getpdevstruct (request);
- struct devstruct *dev = getdevstruct (pdev->unit);
+ struct devstruct *dev;
- put_byte (request+8, NT_MESSAGE);
- if (!dev || !pdev) {
+ put_byte (request + 8, NT_MESSAGE);
+ if (!pdev) {
+ put_byte (request + 31, 32);
+ return get_byte (request + 31);
+ }
+ dev = getdevstruct (pdev->unit);
+ if (!dev) {
put_byte (request + 31, 32);
return get_byte (request + 31);
}