Index: trunk/src/VBox/Devices/PC/BIOS/ata.c
===================================================================
--- trunk/src/VBox/Devices/PC/BIOS/ata.c	(revision 78570)
+++ trunk/src/VBox/Devices/PC/BIOS/ata.c	(revision 78571)
@@ -638,5 +638,5 @@
                     fdpt = ebda_seg :> &EbdaData->fdpt1;
 
-#if 0
+#if 1
                 /* Place the FDPT outside of conventional memory. Needed for
                  * 286 XENIX 2.1.3/2.2.1 because it completely wipes out
Index: trunk/src/VBox/Devices/PC/BIOS/disk.c
===================================================================
--- trunk/src/VBox/Devices/PC/BIOS/disk.c	(revision 78570)
+++ trunk/src/VBox/Devices/PC/BIOS/disk.c	(revision 78571)
@@ -162,5 +162,10 @@
             dpt->heads     = bios_dsk->devices[device].pchs.heads;
             dpt->spt       = bios_dsk->devices[device].pchs.spt;
+#if 1
             lba = bios_dsk->devices[device].sectors;
+#else
+            // Makes PC DOS 7.1 FDISK32 happy
+            lba = (uint32_t)dpt->cylinders * dpt->heads * dpt->spt;
+#endif
             dpt->sector_count1 = lba;
             dpt->sector_count2 = lba >> 32;
@@ -395,8 +400,27 @@
         break;
 
+#ifdef VBOX_WITH_SCSIz
+    case 0x06: /* identify SCSI devices */
+        if (VBOX_IS_SCSI_DEVICE(device)|| 1) {
+            BX_INFO("%s: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", __func__, AX, BX, CX, DX, ES);
+            BX_INFO("%s: function %02xh detected SCSI drive\n", __func__, GET_AH());
+            SET_BH(0);
+            SET_BL(0);
+            SET_AL(0x80);
+            goto int13_success;
+        }
+        BX_INFO("%s no SCSI drives, returns fail\n", __func__);
+        goto int13_fail;
+        break;
+#endif
     case 0x08: /* read disk drive parameters */
 
         /* Get the logical geometry from internal table. */
+#if 0
+        /* Windows 3.1 FastDisk (wdctrl) insists on this */
+        nlc   = bios_dsk->devices[device].lchs.cylinders - 1;
+#else
         nlc   = bios_dsk->devices[device].lchs.cylinders;
+#endif
         nlh   = bios_dsk->devices[device].lchs.heads;
         nlspt = bios_dsk->devices[device].lchs.spt;
Index: trunk/src/VBox/Devices/PC/BIOS/makefile
===================================================================
--- trunk/src/VBox/Devices/PC/BIOS/makefile	(revision 78570)
+++ trunk/src/VBox/Devices/PC/BIOS/makefile	(revision 78571)
@@ -47,5 +47,9 @@
 
 vbxbios.rom : vbxbios.bin
+!if $(CPU) > 286
 	biossums $< $@
+!else
+	cp $< $@
+!endif
 
 vbxbios.bin : $(OBJS) $(__MAKEFILES__)
Index: trunk/src/VBox/Devices/PC/DevACPI.cpp
===================================================================
--- trunk/src/VBox/Devices/PC/DevACPI.cpp	(revision 78570)
+++ trunk/src/VBox/Devices/PC/DevACPI.cpp	(revision 78571)
@@ -2114,5 +2114,4 @@
 {
     ACPIState *pThis = (ACPIState *)pvUser;
-    DEVACPI_LOCK_R3(pThis);
 
     LogFunc(("Port=%#x u32=%#x cb=%u\n", Port, u32, cb));
@@ -2122,4 +2121,5 @@
         return PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "cb=%d Port=%u u32=%#x\n", cb, Port, u32);
 
+    DEVACPI_LOCK_R3(pThis);
     switch (off)
     {
@@ -2203,5 +2203,4 @@
     RT_NOREF1(pDevIns);
     ACPIState *pThis = (ACPIState *)pvUser;
-    DEVACPI_LOCK_R3(pThis);
 
     int rc = VINF_SUCCESS;
@@ -2212,4 +2211,5 @@
         return VERR_IOM_IOPORT_UNUSED;
 
+    DEVACPI_LOCK_R3(pThis);
     switch (off)
     {
Index: trunk/src/VBox/Devices/PC/DevDMA.cpp
===================================================================
--- trunk/src/VBox/Devices/PC/DevDMA.cpp	(revision 78570)
+++ trunk/src/VBox/Devices/PC/DevDMA.cpp	(revision 78571)
@@ -99,4 +99,5 @@
 #define DMA_SAVESTATE_OLD       1   /* The original saved state. */
 #define DMA_SAVESTATE_CURRENT   2   /* The new and improved saved state. */
+#define DMA_FIXES
 
 /* State information for a single DMA channel. */
@@ -266,7 +267,4 @@
             else
                 ch->u16BaseAddr  = RT_MAKE_U16(ch->u16BaseAddr, u32);
-
-            ch->u16CurCount = 0;
-            ch->u16CurAddr  = ch->u16BaseAddr;
         }
         else
@@ -278,4 +276,16 @@
                 ch->u16BaseAddr  = RT_MAKE_U16(u32, RT_HIBYTE(ch->u16BaseAddr));
         }
+        /*
+         * Update the current count/address.
+         *
+         * NB: The current count actually counts from zero up, while the base count
+         * uses the the 8257 semantics and counts down. The guest never sees the
+         * current count directly.
+         */
+        if (is_count)
+            ch->u16CurCount = 0;
+        else
+            ch->u16CurAddr  = ch->u16BaseAddr;
+
         Log2(("dmaWriteAddr: port %#06x, chidx %d, data %#02x\n",
               port, chidx, u32));
@@ -312,5 +322,9 @@
             val = ch->u16BaseCount - ch->u16CurCount;
         else
+#ifdef DMA_FIXES
+            val = ch->u16CurAddr;
+#else
             val = ch->u16CurAddr + ch->u16CurCount * dir;
+#endif
 
         bptr = dmaReadBytePtr(dc);
@@ -601,4 +615,5 @@
     DMAChannel  *ch = &dc->ChState[chidx];
     uint32_t    start_cnt, end_cnt;
+    int         uDelta;
     int         opmode;
 
@@ -616,5 +631,10 @@
     end_cnt = ch->pfnXferHandler(pThis->pDevIns, ch->pvUser, (ctlidx * 4) + chidx,
                                  start_cnt, (ch->u16BaseCount + 1) << dc->is16bit);
+    uDelta = (end_cnt - start_cnt) >> dc->is16bit;
     ch->u16CurCount = end_cnt >> dc->is16bit;
+#ifdef DMA_FIXES    // Necessary, but currently upsets SB16.
+    int dir = IS_MODE_DEC(ch->u8Mode) ? -1 : 1;
+    ch->u16CurAddr += uDelta * dir;
+#endif
     /* Set the TC (Terminal Count) bit if transfer was completed. */
     if (ch->u16CurCount == ch->u16BaseCount + 1)
@@ -624,6 +644,16 @@
         case DMODE_SINGLE:
         case DMODE_BLOCK:
-            dc->u8Status |= RT_BIT(chidx);
-            Log3(("TC set for DMA channel %d\n", (ctlidx * 4) + chidx));
+            dc->u8Status |= RT_BIT(chidx);  /* Set the TC status bit. */
+            Log3(("TC set for DMA channel %d, auto-init %s\n", (ctlidx * 4) + chidx, IS_MODE_AI(ch->u8Mode) ? "on" : "off"));
+            if (IS_MODE_AI(ch->u8Mode))
+            {
+                /* Auto-init DMA, resets the current address/count. */
+#ifdef DMA_FIXES    // Necessary, but currently upsets SB16.
+                ch->u16CurAddr  = ch->u16BaseAddr;
+                ch->u16CurCount = 0;
+#endif
+            }
+            else
+                dc->u8Mask |= RT_BIT(chidx);    /* No auto-init, mask channel. */
             break;
         default:
@@ -655,4 +685,5 @@
         {
             mask = 1 << chidx;
+            /* Run channel if not masked and its DREQ is active. */
             if (!(dc->u8Mask & mask) && (dc->u8Status & (mask << 4)))
                 dmaRunChannel(pThis, ctlidx, chidx);
