]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
imported winuaesrc1420b4.zip
authorToni Wilen <twilen@winuae.net>
Fri, 6 Apr 2007 12:50:50 +0000 (15:50 +0300)
committerToni Wilen <twilen@winuae.net>
Mon, 22 Feb 2010 19:32:53 +0000 (21:32 +0200)
22 files changed:
ar.c
autoconf.c
custom.c
drawing.c
expansion.c
filesys.c
gayle.c
hardfile.c
include/gayle.h
include/memory.h
include/savestate.h
memory.c
newcpu.c
od-win32/parser.c
od-win32/picasso96_win.c
od-win32/resources/winuae.rc
od-win32/win32.h
od-win32/win32gui.c
od-win32/win32gui_extra.c
od-win32/winuaechangelog.txt
savestate.c
scsiemul.c

diff --git a/ar.c b/ar.c
index e19cf5a2510142cc0523d5015672601943377eb4..aec5f8f2fdd2f1176d5de576677f3ff9476c687c 100755 (executable)
--- a/ar.c
+++ b/ar.c
@@ -193,7 +193,7 @@ static void hrtmon_unmap_banks(void);
 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)
 {
@@ -205,7 +205,9 @@ 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
 }
 
index 69072c492bd1d57af0e9922633fddd1540634462..04b9521fcf5c3acf4c0e9c6de7c34dfe20d805a0 100755 (executable)
@@ -240,6 +240,7 @@ void rtarea_init (void)
     filesys_install_code ();
 #endif
 
+    uae_boot_rom_size = here() - RTAREA_BASE;
     init_extended_traps();
 }
 
index 1e96d6f4d0cb9095aec9ed89af6a62072b4be522..e0a8e7d38d89e6b910288c13eebf911de7fa74ea 100755 (executable)
--- a/custom.c
+++ b/custom.c
@@ -56,6 +56,7 @@
 #if defined(ENFORCER)
 #include "enforcer.h"
 #endif
+#include "gayle.h"
 
 STATIC_INLINE int nocustom(void)
 {
@@ -4445,6 +4446,7 @@ static void hsync_handler (void)
     }
 
     inputdevice_hsync ();
+    mbdmac_hsync();
 
     hsync_counter++;
     //copper_check (2);
index bd607ac8c179f54b644543cf5fac04da4ab60e55..18e2c0100125976ba4b24126fd194448ac020703 100755 (executable)
--- a/drawing.c
+++ b/drawing.c
@@ -2386,10 +2386,12 @@ void drawing_init (void)
 
     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;
index 53bacf826cc257ef201bc5407f52955c24f32216..e3db1390d060163c3cab0a3e60e31f747ca29090 100755 (executable)
@@ -125,7 +125,7 @@ uaecptr ROM_filesys_resname, ROM_filesys_resid;
 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 */
 
 /* ********************************************************** */
 
@@ -1247,7 +1247,8 @@ uae_u8 *save_expansion (int *len, uae_u8 *dstptr)
     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;
 }
 
@@ -1256,6 +1257,7 @@ uae_u8 *restore_expansion (uae_u8 *src)
     fastmem_start = restore_u32 ();
     z3fastmem_start = restore_u32 ();
     gfxmem_start = restore_u32 ();
+    restore_u32();
     return src;
 }
 
index 9cc99844b53bcb9caa6092c779be77cd7d011a46..f095ca6a363259fb1cdb788ea0df80ea6981b0f2 100755 (executable)
--- a/filesys.c
+++ b/filesys.c
@@ -89,6 +89,7 @@ static void aino_test_init (a_inode *aino)
 
 uaecptr filesys_initcode;
 static uae_u32 fsdevname, filesys_configdev;
+static int filesys_in_interrupt;
 
 #define FS_STARTUP 0
 #define FS_GO_DOWN 1
@@ -1033,6 +1034,17 @@ static char *get_aname (Unit *unit, a_inode *base, char *rel)
     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;
@@ -1053,13 +1065,7 @@ static void init_child_aino (Unit *unit, a_inode *base, a_inode *aino)
        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);
@@ -1259,6 +1265,47 @@ static a_inode *get_aino (Unit *unit, a_inode *base, const char *rel, uae_u32 *e
     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)
@@ -1299,6 +1346,17 @@ static Unit *startup_create_unit (UnitInfo *uinfo)
     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;
@@ -1566,39 +1624,6 @@ static uaecptr make_lock (Unit *unit, uae_u32 uniq, long mode)
     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
 
@@ -3302,6 +3327,7 @@ static uae_u32 REGPARAM2 exter_int_helper (TrapContext *context)
            /* 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;
@@ -3416,6 +3442,7 @@ static uae_u32 REGPARAM2 exter_int_helper (TrapContext *context)
         break;
      case 4:
        /* Exit the interrupt, and release the single-threading lock. */
+        filesys_in_interrupt--;
        uae_sem_post (&singlethread_int_sem);
        break;
 
@@ -3598,12 +3625,11 @@ static void init_filesys_diagentry (void)
 
 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;
@@ -3617,13 +3643,13 @@ void filesys_start_threads (void)
        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);
     }
 }
 
@@ -3728,8 +3754,6 @@ static uae_u32 REGPARAM2 filesys_diagentry (TrapContext *context)
     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 */
@@ -4291,6 +4315,9 @@ void filesys_install (void)
 
     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");
 
@@ -4347,13 +4374,340 @@ void filesys_install_code (void)
 }
 #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 ();
@@ -4362,26 +4716,136 @@ static uae_u8 *restore_filesys_virtual (UnitInfo *ui, uae_u8 *src)
     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);
@@ -4390,33 +4854,87 @@ static uae_u8 *save_filesys_virtual (UnitInfo *ui, uae_u8 *dst)
     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);
@@ -4429,6 +4947,8 @@ uae_u8 *save_filesys (int num, int *len)
     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;
 }
@@ -4440,7 +4960,7 @@ uae_u8 *restore_filesys (uae_u8 *src)
     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 ();
@@ -4450,14 +4970,17 @@ uae_u8 *restore_filesys (uae_u8 *src)
     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:
@@ -4467,3 +4990,10 @@ end:
     xfree (filesysdir);
     return src;
 }
+
+int save_filesys_cando(void)
+{
+    if (nr_units() == 0)
+       return -1;
+    return filesys_in_interrupt ? 0 : 1;
+}
diff --git a/gayle.c b/gayle.c
index 565906388f092817702128c05e18c14a2a99ece6..d528fd183218893584b899e8efcf96fc4adcd08c 100755 (executable)
--- a/gayle.c
+++ b/gayle.c
@@ -6,6 +6,8 @@
   * (c) 2006 Toni Wilen
   */
 
+#define GAYLE_LOG 0
+
 #include "sysconfig.h"
 #include "sysdeps.h"
 
@@ -24,7 +26,7 @@ DA4000 to DA4FFF              16 KB IDE reserved
 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
 */
 
@@ -66,8 +68,6 @@ 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)
@@ -315,17 +315,206 @@ addrbank mbres_bank = {
     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;
@@ -337,16 +526,15 @@ static void REGPARAM3 mbdmac_bput (uaecptr, uae_u32) 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)
@@ -357,18 +545,19 @@ 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
 };
 
index c45466acef33d3ae7935daa03b297964589bbff3..52651adddc8eb73bb8adbffe9230ab6f2aa4d008 100755 (executable)
@@ -86,7 +86,7 @@ struct hardfileprivdata {
     uae_thread_id tid;
     int thread_running;
     uae_sem_t sync_sem;
-    int opencount;
+    uaecptr base;
 };
 
 static uae_sem_t change_sem;
@@ -364,13 +364,14 @@ static void abort_async (struct hardfileprivdata *hfpd, uaecptr request, int err
 }
 
 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);
@@ -397,9 +398,8 @@ static uae_u32 REGPARAM2 hardfile_open (TrapContext *context)
     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 */
@@ -420,12 +420,11 @@ static uae_u32 REGPARAM2 hardfile_close (TrapContext *context)
     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;
 }
 
@@ -680,7 +679,8 @@ static uae_u32 REGPARAM2 hardfile_abortio (TrapContext *context)
     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);
@@ -726,7 +726,8 @@ static uae_u32 REGPARAM2 hardfile_beginio (TrapContext *context)
     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);
     }
@@ -778,7 +779,7 @@ void hardfile_reset (void)
 
     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]))
index ef6f89bd1a95a82a323fb19ac19ae61950fce8a3..1453de9bd231141dd7752d80b103120f26d75ba8 100755 (executable)
@@ -1,2 +1,3 @@
 
 void gayle_reset(int);
+void mbdmac_hsync(void);
index d4384b2f597fc4e47734dd9ab080595b1144977d..3090ad4b516caf443d8f6997365d6a9feb4c292f 100755 (executable)
@@ -64,7 +64,7 @@ extern uaecptr a3000lmem_start, a3000hmem_start;
 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[];
 
index 02a3ceee21377716bf63411c3dd10e5c838745c1..b57b97d138df37bffe87e98a8a17652c9657d047 100755 (executable)
@@ -82,11 +82,15 @@ extern uae_u8 *save_keyboard (int *);
 
 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);
@@ -97,6 +101,7 @@ extern uae_u8 *save_cram (int *);
 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 *);
@@ -110,7 +115,7 @@ extern uae_u8 *restore_hrtmon (uae_u8 *);
 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);
 
index b64e7d2b89d835ff7d1bc5aa07dddf33e378c9d4..d51e736252e660744febd6d8d6c3177345bb2053 100755 (executable)
--- a/memory.c
+++ b/memory.c
@@ -50,7 +50,7 @@ uae_u32 max_z3fastmem = 2048UL * 1024 * 1024;
 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;
@@ -2188,6 +2188,7 @@ static void allocate_memory (void)
        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);
@@ -2385,8 +2386,10 @@ void memory_reset (void)
     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) {
@@ -2484,6 +2487,8 @@ void memory_cleanup (void)
 
 void memory_hardreset(void)
 {
+    if (savestate_state == STATE_RESTORE)
+       return;
     if (chipmemory)
        memset (chipmemory, 0, allocated_chipmem);
     if (bogomemory)
@@ -2557,6 +2562,14 @@ void map_banks (addrbank *bank, int start, int size, int realsize)
 
 /* 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;
@@ -2581,6 +2594,11 @@ uae_u8 *save_a3000hram (int *len)
     return a3000hmemory;
 }
 
+void restore_bootrom (int len, size_t filepos)
+{
+    bootrom_filepos = filepos;
+}
+
 void restore_cram (int len, size_t filepos)
 {
     chip_filepos = filepos;
index 761f1fd9af70ca5e2025b88313883fe5e49c56f6..28187fd44b0f85a14de0fb4030dacdb019a0a5c6 100755 (executable)
--- a/newcpu.c
+++ b/newcpu.c
@@ -77,7 +77,7 @@ cpuop_func *cpufunctbl[65536];
 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
@@ -130,6 +130,21 @@ void dump_counts (void)
 }
 #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)
 {
 }
@@ -247,6 +262,17 @@ static void update_68k_cycles (void)
     }
 }
 
+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
@@ -254,13 +280,7 @@ void check_prefs_changed_cpu (void)
        || 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 (&regs);
        build_cpufunctbl ();
@@ -279,8 +299,7 @@ void init_m68k (void)
 {
     int i;
 
-    fixup_cpu (&changed_prefs);
-    fixup_cpu (&currprefs);
+    prefs_changed_cpu ();
     update_68k_cycles ();
 
     for (i = 0 ; i < 256 ; i++) {
@@ -351,6 +370,7 @@ void init_m68k (void)
     /* We need to check whether NATMEM settings have changed
      * before starting the CPU */
     check_prefs_changed_comp ();
+    set_cpu_caches();
 #endif
 }
 
@@ -1078,7 +1098,7 @@ void REGPARAM2 Exception (int nr, struct regstruct *regs, uaecptr oldpc)
 #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)
@@ -1108,8 +1128,6 @@ void Interrupt (int nr)
     do_interrupt (nr, &regs);
 }
 
-static uae_u32 caar, cacr, itt0, itt1, dtt0, dtt1, tcr, mmusr, urp, srp, buscr;
-
 #ifndef CPUEMU_68000_ONLY
 
 static int movec_illg (int regno)
@@ -1170,19 +1188,7 @@ int m68k_move2c (int regno, uae_u32 *regp)
            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 */
@@ -1556,7 +1562,7 @@ void m68k_reset (void)
     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;
@@ -1729,17 +1735,17 @@ static void do_trace (void)
        m68k_setpc (&regs, m68k_getpc (&regs));
        fill_prefetch_slow (&regs);
        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(&regs.ccrflags, (opcode >> 8) & 0xf))
-           || ((opcode & 0xf0f0) == 0x5050 /* DBcc */
+           || ((opcode & 0xf0f0) == 0x5050     /* DBcc */
                && !cctrue(&regs.ccrflags, (opcode >> 8) & 0xf)
                && (uae_s16)m68k_dreg(&regs, opcode & 7) != 0))
        {
@@ -2105,7 +2111,7 @@ void execute_normal(void)
        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 */
        }
@@ -2279,6 +2285,7 @@ void m68k_go (int may_quit)
            if (savestate_state == STATE_RESTORE || savestate_state == STATE_REWIND) {
                map_overlay (1);
                fill_prefetch_slow (&regs); /* compatibility with old state saves */
+               memory_map_dump();
            }
            savestate_restore_finish ();
 #endif
@@ -2714,6 +2721,7 @@ void restore_cpu_finish(void)
 {
     init_m68k ();
     m68k_setpc (&regs, regs.pc);
+    set_cpu_caches();
 }
 
 uae_u8 *save_cpu (int *len, uae_u8 *dstptr)
index a840c4988b98f8e27f3557eec50751b31ed89401..d62611294e1dbb95dd0be60e40bfb1dc124d234d 100755 (executable)
@@ -43,6 +43,7 @@
 #include "zfile.h"
 #include "threaddep/thread.h"
 #include "serial.h"
+#include "savestate.h"
 
 #include <Ghostscript/errors.h>
 #include <Ghostscript/iapi.h>
index 1ebda6130ef6a86091073208e6210f73b928349c..76c724e5140532a71fef56c162a58ad69f59064b 100755 (executable)
@@ -144,7 +144,7 @@ static void checkrtglibrary(void)
 }
 
 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
@@ -940,10 +940,10 @@ void picasso_handle_vsync (void)
        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) { 
@@ -975,12 +975,13 @@ void picasso_refresh (int call_setpalette)
     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;
@@ -1841,8 +1842,12 @@ uae_u32 REGPARAM2 picasso_SetSwitch (struct regstruct *regs)
     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");
@@ -1907,14 +1912,12 @@ uae_u32 REGPARAM2 picasso_SetDAC (struct regstruct *regs)
 }
 
 
-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);
     }
@@ -1926,6 +1929,7 @@ static void init_picasso_screen( void )
        DX_SetPalette (0, 256);
        picasso_refresh (1); 
     }
+    init_picasso_screen_called = 1;
 }
 
 /*
@@ -1985,12 +1989,23 @@ uae_u32 REGPARAM2 picasso_SetGC (struct regstruct *regs)
   * 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) {
@@ -2001,24 +2016,18 @@ uae_u32 REGPARAM2 picasso_SetPanning (struct regstruct *regs)
        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,
@@ -3812,15 +3821,67 @@ void InitPicasso96 (void)
 
 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
index 9dad3e10d7e09342b47dbf2f0df6ec5e0da6ecc3..856926fc095f511f12afbe285f43d8e7a69c1cdf 100755 (executable)
@@ -155,7 +155,7 @@ BEGIN
     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,
@@ -172,14 +172,14 @@ BEGIN
     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
@@ -1194,9 +1194,9 @@ BEGIN
     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 
@@ -1214,7 +1214,7 @@ BEGIN
     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."
index 9981e7769b29c1ae3605a691925c2ca4ae9ae6a6..bbd359feae4d7dfa1c7e4849674db1c8d8986483 100755 (executable)
@@ -15,9 +15,9 @@
 #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)
index 9dc0da7f5207df41054deb98398f05650d40071b..8646c24a5d342373f197701f52aa3796afc0bba4 100755 (executable)
@@ -5249,7 +5249,7 @@ static void values_to_cpudlg (HWND hDlg)
 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;
@@ -5317,11 +5317,19 @@ static void values_from_cpudlg (HWND hDlg)
     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;
index 08806f222d49e9d6e687c2c3ea969ba5fb20b95b..4d3aba7067377305c72c8650dd8eaa9c1d93e580 100755 (executable)
@@ -1,6 +1,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <windows.h>
+#include <Wingdi.h>
 #include <winspool.h>
 #include <winuser.h>
 #include <mmsystem.h>
@@ -65,9 +66,12 @@ typedef struct {
     /* 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)
@@ -100,11 +104,11 @@ static void modifytemplatefont(DLGTEMPLATEEX *d, DLGTEMPLATEEX_END *d2)
 {
     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);
 }
 
@@ -200,8 +204,40 @@ void freescaleresource(struct newresource *ns)
     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;
index 045d53b1bc9312f5686d196eb168b610ad01e740..5f59bf00a771b1eb7e71f7a52b7eb4acfd040576 100755 (executable)
@@ -1,4 +1,44 @@
 
+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
index b39a736f85ad4bab489568a49b04c85180cb6627..c5d45ed33c00670d6482b0983f72b50efcf1478d 100755 (executable)
@@ -58,6 +58,7 @@
 #include "uae.h"
 #include "gui.h"
 #include "audio.h"
+#include "filesys.h"
 
 int savestate_state = 0;
 
@@ -80,6 +81,42 @@ static int replaybuffersize;
 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 */
 
@@ -381,6 +418,9 @@ void restore_state (char *filename)
        } 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")) {
@@ -458,6 +498,8 @@ void restore_state (char *filename)
 #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);
@@ -514,18 +556,20 @@ static void save_rams (struct zfile *f, int comp)
     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];
@@ -534,20 +578,18 @@ void save_state (char *filename, char *description)
     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)
@@ -568,7 +610,7 @@ void save_state (char *filename, char *description)
            xfree(tmp);
        }
        zfile_fclose (f);
-       return;
+       return 1;
     }
 
     dst = header;
@@ -663,11 +705,15 @@ void save_state (char *filename, char *description)
     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
@@ -677,6 +723,7 @@ void save_state (char *filename, char *description)
     write_log ("Save of '%s' complete\n", filename);
     zfile_fclose (f);
     savestate_state = 0;
+    return 1;
 }
 
 void savestate_quick (int slot, int save)
index a3b6b6798bce3a56e816b615a1f0d90007df8f60..b663d3ec60f7bfc5f48e1578fb8452cef037f60f 100755 (executable)
@@ -596,10 +596,15 @@ static uae_u32 REGPARAM2 dev_beginio (TrapContext *context)
     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);
     }