diff -urN fs-uae-3.1.66-orig/libfsemu/include/fs/filesys.h fs-uae-3.1.66/libfsemu/include/fs/filesys.h
--- fs-uae-3.1.66-orig/libfsemu/include/fs/filesys.h	2021-12-19 21:24:39 +0900
+++ fs-uae-3.1.66/libfsemu/include/fs/filesys.h	2022-02-15 14:30:50 +0900
@@ -35,6 +35,7 @@
 };
 
 int fs_set_file_time(const char *path, struct timeval *tv);
+int fs_set_file_mode(const char *path, int mode);
 
 int fs_stat(const char *path, struct fs_stat *buf);
 int fs_fstat(int fd, struct fs_stat *buf);
diff -urN fs-uae-3.1.66-orig/src/od-fs/fsdb_host.cpp fs-uae-3.1.66/src/od-fs/fsdb_host.cpp
--- fs-uae-3.1.66-orig/src/od-fs/fsdb_host.cpp	2021-12-19 21:24:39 +0900
+++ fs-uae-3.1.66/src/od-fs/fsdb_host.cpp	2022-02-15 14:40:19 +0900
@@ -546,12 +546,30 @@
         if (g_fsdb_debug) {
             write_log("- setting default perms\n");
         }
-        info->mode |= A_FIBF_READ;
-        info->mode |= A_FIBF_WRITE;
-        info->mode |= A_FIBF_EXECUTE;
-        info->mode |= A_FIBF_DELETE;
-        if (! uae_deterministic_mode()) {
-            // FIXME: remove WRITE and DELETE if file is not writable
+        if (uae_deterministic_mode()) {
+            info->mode |= A_FIBF_READ;
+            info->mode |= A_FIBF_WRITE;
+            info->mode |= A_FIBF_EXECUTE;
+            info->mode |= A_FIBF_DELETE;
+        } else {
+            struct fs_stat buf;
+            if (fs_stat(nname, &buf) != 0) {
+                buf.mode = S_IRUSR | S_IWUSR | S_IXUSR;
+            }
+            if (buf.mode & S_IRUSR) {
+                info->mode |= A_FIBF_READ;
+            }
+            if (buf.mode & S_IWUSR) {
+                info->mode |= A_FIBF_WRITE;
+                /* Technically, "delete" permission follows the containing
+                 * directory's write flag, but we default to matching the
+                 * file's own writable flag as a better analog to AmigaOS
+                 * behavior. */
+                info->mode |= A_FIBF_DELETE;
+            }
+            if (buf.mode & S_IXUSR) {
+                info->mode |= A_FIBF_EXECUTE;
+            }
         }
     }
 
@@ -605,8 +623,43 @@
         }
     }
 
-    if (info->mode != (A_FIBF_READ | A_FIBF_WRITE | A_FIBF_EXECUTE | \
+    int host_mode = -1;
+#ifdef WINDOWS
+    if (info->mode == (A_FIBF_READ | A_FIBF_WRITE | A_FIBF_EXECUTE | \
             A_FIBF_DELETE)) {
+        host_mode = 0;
+    }
+#else
+    if (info->mode == 0) {
+        host_mode = 0;
+    } else if (info->mode == A_FIBF_EXECUTE) {
+        host_mode =                     S_IXUSR;
+    } else if (info->mode == (A_FIBF_WRITE | A_FIBF_DELETE)) {
+        host_mode =           S_IWUSR;
+    } else if (info->mode == (A_FIBF_WRITE | A_FIBF_EXECUTE | A_FIBF_DELETE)) {
+        host_mode =           S_IWUSR | S_IXUSR;
+    } else if (info->mode == A_FIBF_READ) {
+        host_mode = S_IRUSR;
+    } else if (info->mode == (A_FIBF_READ | A_FIBF_EXECUTE)) {
+        host_mode = S_IRUSR           | S_IXUSR;
+    } else if (info->mode == (A_FIBF_READ | A_FIBF_WRITE | A_FIBF_DELETE)) {
+        host_mode = S_IRUSR | S_IWUSR;
+    } else if (info->mode == (A_FIBF_READ | A_FIBF_WRITE | A_FIBF_EXECUTE |
+                              A_FIBF_DELETE)) {
+        host_mode = S_IRUSR | S_IWUSR | S_IXUSR;
+    }
+#endif
+    if (host_mode >= 0) {
+#ifndef WINDOWS
+        if (chmod(nname, host_mode) != 0) {
+            if (g_fsdb_debug) {
+                write_log("- errno %d setting file mode 0%03o\n",
+                          errno, host_mode);
+            }
+            error = errno;
+        }
+#endif
+    } else {
         if (g_fsdb_debug) {
             write_log("- mode was %d\n", info->mode);
         }
