Index: trunk/src/VBox/Devices/Storage/DrvVD.cpp
===================================================================
--- trunk/src/VBox/Devices/Storage/DrvVD.cpp	(revision 31098)
+++ trunk/src/VBox/Devices/Storage/DrvVD.cpp	(revision 31128)
@@ -1622,4 +1622,5 @@
     char *pszFormat = NULL; /**< The format backed to use for this image. */
     bool fReadOnly;         /**< True if the media is read-only. */
+    bool fMaybeReadOnly;    /**< True if the media may or may not be read-only. */
     bool fHonorZeroWrites;  /**< True if zero blocks should be written. */
     PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
@@ -1701,5 +1702,5 @@
             fValid = CFGMR3AreValuesValid(pCurNode,
                                           "Format\0Path\0"
-                                          "ReadOnly\0TempReadOnly\0HonorZeroWrites\0"
+                                          "ReadOnly\0MaybeReadOnly\0TempReadOnly\0HonorZeroWrites\0"
                                           "HostIPStack\0UseNewIo\0"
                                           "SetupMerge\0MergeSource\0MergeTarget\0");
@@ -1742,4 +1743,12 @@
                 rc = PDMDRV_SET_ERROR(pDrvIns, rc,
                                       N_("DrvVD: Configuration error: Querying \"ReadOnly\" as boolean failed"));
+                break;
+            }
+
+            rc = CFGMR3QueryBoolDef(pCurNode, "MaybeReadOnly", &fMaybeReadOnly, false);
+            if (RT_FAILURE(rc))
+            {
+                rc = PDMDRV_SET_ERROR(pDrvIns, rc,
+                                      N_("DrvVD: Configuration error: Querying \"MaybeReadOnly\" as boolean failed"));
                 break;
             }
@@ -2014,6 +2023,7 @@
                  iLevel, pszName,
                  VDIsReadOnly(pThis->pDisk) ? "read-only" : "read-write"));
-            if (   VDIsReadOnly(pThis->pDisk)
+            if (  VDIsReadOnly(pThis->pDisk)
                 && !fReadOnly
+                && !fMaybeReadOnly
                 && !pThis->fTempReadOnly
                 && iLevel == 0)
Index: trunk/src/VBox/Devices/Storage/fdc.c
===================================================================
--- trunk/src/VBox/Devices/Storage/fdc.c	(revision 31098)
+++ trunk/src/VBox/Devices/Storage/fdc.c	(revision 31128)
@@ -1280,4 +1280,14 @@
             /* WRITE commands */
 #ifdef VBOX
+            if (cur_drv->ro)
+            {
+                /* Handle readonly medium early, no need to do DMA, touch the
+                 * LED or attempt any writes. A real floppy doesn't attempt
+                 * to write to readonly media either. */
+                fdctrl_stop_transfer (fdctrl, 0x60, 0x00 | (cur_drv->ro << 1),
+                                      0x00);
+                goto transfer_error;
+            }
+
             {
                 uint32_t written;
@@ -1288,18 +1298,5 @@
                 AssertMsgRC (rc2, ("DMAReadMemory -> %Rrc\n", rc2));
             }
-#else
-            DMA_read_memory (nchan, fdctrl->fifo + rel_pos,
-                             fdctrl->data_pos, len);
-#endif
-/*             cpu_physical_memory_read(addr + fdctrl->data_pos, */
-/*                                   fdctrl->fifo + rel_pos, len); */
-#ifndef VBOX
-            if (bdrv_write(cur_drv->bs, fd_sector(cur_drv),
-                           fdctrl->fifo, 1) < 0) {
-                FLOPPY_ERROR("writting sector %d\n", fd_sector(cur_drv));
-                fdctrl_stop_transfer(fdctrl, 0x60, 0x00, 0x00);
-                goto transfer_error;
-            }
-#else  /* VBOX */
+
             cur_drv->Led.Asserted.s.fWriting
                 = cur_drv->Led.Actual.s.fWriting = 1;
@@ -1315,7 +1312,19 @@
 
             if (RT_FAILURE (rc)) {
-                AssertMsgFailed (("Floppy: error writing sector %d. rc=%Rrc",
-                                  fd_sector (cur_drv), rc));
-                fdctrl_stop_transfer (fdctrl, 0x60, 0x00, 0x00);
+                AssertMsgFailed(("Floppy: error writing sector %d. rc=%Rrc",
+                                 fd_sector (cur_drv), rc));
+                fdctrl_stop_transfer (fdctrl, 0x60, 0x00 | (cur_drv->ro << 1),
+                                      0x00);
+                goto transfer_error;
+            }
+#else
+            DMA_read_memory (nchan, fdctrl->fifo + rel_pos,
+                             fdctrl->data_pos, len);
+/*             cpu_physical_memory_read(addr + fdctrl->data_pos, */
+/*                                   fdctrl->fifo + rel_pos, len); */
+            if (bdrv_write(cur_drv->bs, fd_sector(cur_drv),
+                           fdctrl->fifo, 1) < 0) {
+                FLOPPY_ERROR("writting sector %d\n", fd_sector(cur_drv));
+                fdctrl_stop_transfer(fdctrl, 0x60, 0x00, 0x00);
                 goto transfer_error;
             }
