diff --git a/include/miscemu.h b/include/miscemu.h
index 865eb1ad7bb25950a4955bf491079c19b36dd53e..32bba50e01c0f5f6c4ca44f018d80ecceb08f9b2 100644
--- a/include/miscemu.h
+++ b/include/miscemu.h
@@ -74,6 +74,51 @@ typedef struct
     BYTE  DiskDataRate;              /* 8B: Last disk data rate selected */
 } BIOSDATA;
 
+typedef struct
+{
+    DWORD StaticFuncTable;           /* 00: static functionality table */
+    BYTE  VideoMode;                 /* 04: video mode in effect */
+    WORD  NumberColumns;             /* 05: number of columns */
+    WORD  RegenBufLen;               /* 07: length of regen buffer in bytes */
+    WORD  RegenBufAddr;              /* 09: starting address of regen buffer */
+    WORD  CursorPos[8];              /* 0B: cursor position for page 0..7 */
+    WORD  CursorType;                /* 1B: cursor "type" (start/stop scan lines) */
+    BYTE  ActivePage;                /* 1D: active display page */
+    WORD  CRTCPort;                  /* 1E: CRTC port address */
+    BYTE  Port3x8;                   /* 20: current setting of PORT 03x8h */
+    BYTE  Port3x9;                   /* 21: current setting of PORT 03x9h */
+    BYTE  NumberRows;                /* 22: number of rows - 1 */
+    WORD  BytesPerChar;              /* 23: bytes/character */
+    BYTE  DCCActive;                 /* 25: display combination code of active display */
+    BYTE  DCCAlternate;              /* 26: DCC of alternate display */
+    WORD  NumberColors;              /* 27: number of colors supported in current mode (0000h = mono) */
+    BYTE  NumberPages;               /* 29: number of pages supported in current mode */
+    BYTE  NumberScanlines;           /* 2A: number of scan lines active */
+    BYTE  CharBlockPrimary;          /* 2B: primary character block */
+    BYTE  CharBlockSecondary;        /* 2C: secondary character block */
+    BYTE  MiscFlags;                 /* 2D: miscellaneous flags */
+    BYTE  NonVGASupport;             /* 2E: non-VGA mode support */
+    BYTE  _reserved1[2];             /* 2F: */
+    BYTE  VideoMem;                  /* 31: video memory available */
+    BYTE  SavePointerState;          /* 32: save pointer state flags */
+    BYTE  DisplayStatus;             /* 33: display information and status */
+    BYTE  _reserved2[12];            /* 34: */
+
+} VIDEOSTATE;
+
+typedef struct
+{
+    BYTE  ModeSupport[7];           /* 00: modes supported 1..7 */
+    BYTE  ScanlineSupport;          /* 07: scan lines supported */
+    BYTE  NumberCharBlocks;         /* 08: total number of character blocks */
+    BYTE  ActiveCharBlocks;         /* 09: max. number of active character blocks */
+    WORD  MiscFlags;                /* 0A: miscellaneous function support flags */
+    WORD  _reserved1;               /* 0C: */
+    BYTE  SavePointerFlags;         /* 0E: save pointer function flags */
+    BYTE  _reserved2;               /* OF: */
+
+} VIDEOFUNCTIONALITY;
+
 #include "poppack.h"
 
 extern HANDLE16 DOSMEM_BiosDataSeg;
diff --git a/msdos/devices.c b/msdos/devices.c
index 5d3632806f742afae3acb5f430aa6ad76bc34a00..a3d08639d5ba6ca04d3066c1605b83a6570335bc 100644
--- a/msdos/devices.c
+++ b/msdos/devices.c
@@ -15,12 +15,11 @@
 #include "pshpack1.h"
 
 typedef struct {
-  DOS_DEVICE_HEADER hdr;
   BYTE ljmp1;
   RMCBPROC strategy;
   BYTE ljmp2;
   RMCBPROC interrupt;
-} WINEDEV;
+} WINEDEV_THUNK;
 
 typedef struct {
   BYTE size; /* length of header + data */
@@ -46,13 +45,11 @@ typedef struct {
 
 #include "poppack.h"
 
-#define REQ_SCRATCH sizeof(REQ_IO)
+#define CON_BUFFER 128
 
 #define SYSTEM_STRATEGY_NUL 0x0100
 #define SYSTEM_STRATEGY_CON 0x0101
 
-DWORD DOS_LOLSeg;
-
 #define NONEXT ((DWORD)-1)
 
 #define ATTR_STDIN     0x0001
@@ -94,10 +91,6 @@ DWORD DOS_LOLSeg;
 
 #define LJMP 0xea
 
-#define DEV0_OFS (sizeof(DOS_LISTOFLISTS) - sizeof(DOS_DEVICE_HEADER))
-#define DEV1_OFS (DEV0_OFS + sizeof(WINEDEV))
-#define ALLDEV_OFS (DEV1_OFS + sizeof(devs))
-#define ALL_OFS (ALLDEV_OFS + REQ_SCRATCH)
 
 /* prototypes */
 static void WINAPI nul_strategy(CONTEXT86*ctx);
@@ -105,27 +98,44 @@ static void WINAPI nul_interrupt(CONTEXT86*ctx);
 static void WINAPI con_strategy(CONTEXT86*ctx);
 static void WINAPI con_interrupt(CONTEXT86*ctx);
 
-/* the device headers */
-#define STRATEGY_OFS sizeof(DOS_DEVICE_HEADER)
-#define INTERRUPT_OFS STRATEGY_OFS+5
+/* devices */
+typedef struct 
+{
+    char name[8];
+    WORD attr;
+    RMCBPROC strategy;
+    RMCBPROC interrupt;
+    
+} WINEDEV;
+
+static WINEDEV devs[] = 
+{
+  { "NUL     ",
+    ATTR_CHAR|ATTR_NUL|ATTR_DEVICE,
+    nul_strategy, nul_interrupt },
 
-static DOS_DEVICE_HEADER dev_nul_hdr={
- NONEXT,
- ATTR_CHAR|ATTR_NUL|ATTR_DEVICE,
- STRATEGY_OFS,INTERRUPT_OFS,
- "NUL     "
+  { "CON     ",
+    ATTR_CHAR|ATTR_STDIN|ATTR_STDOUT|ATTR_FASTCON|ATTR_NOTEOF|ATTR_DEVICE,
+    con_strategy, con_interrupt }
 };
 
-static WINEDEV devs[]={
+#define NR_DEVS (sizeof(devs)/sizeof(WINEDEV))
+
+/* DOS data segment */
+typedef struct
 {
- {NONEXT,
-  ATTR_CHAR|ATTR_STDIN|ATTR_STDOUT|ATTR_FASTCON|ATTR_NOTEOF|ATTR_DEVICE,
-  STRATEGY_OFS,INTERRUPT_OFS,
-  "CON     "},
- LJMP,con_strategy,
- LJMP,con_interrupt}
-};
-#define nr_devs (sizeof(devs)/sizeof(WINEDEV))
+    DOS_LISTOFLISTS    lol;
+    DOS_DEVICE_HEADER  dev[NR_DEVS-1];
+    WINEDEV_THUNK      thunk[NR_DEVS];
+    REQ_IO             req;
+    BYTE               buffer[CON_BUFFER];
+
+} DOS_DATASEG;
+
+#define DOS_DATASEG_OFF(xxx) FIELD_OFFSET(DOS_DATASEG, xxx)
+
+DWORD DOS_LOLSeg;
+
 
 /* the device implementations */
 static void do_lret(CONTEXT86*ctx)
@@ -182,8 +192,6 @@ static void WINAPI nul_interrupt(CONTEXT86*ctx)
   do_lret(ctx);
 }
 
-#define CON_BUFFER 128
-
 static void WINAPI con_strategy(CONTEXT86*ctx)
 {
   do_strategy(ctx, SYSTEM_STRATEGY_CON, sizeof(int));
@@ -196,10 +204,11 @@ static void WINAPI con_interrupt(CONTEXT86*ctx)
   BIOSDATA *bios = DOSMEM_BiosData();
   WORD CurOfs = bios->NextKbdCharPtr;
   DOS_LISTOFLISTS *lol = DOSMEM_LOL();
-  BYTE *linebuffer = ((BYTE*)lol) + ALL_OFS;
+  DOS_DATASEG *dataseg = (DOS_DATASEG *)lol;
+  BYTE *linebuffer = dataseg->buffer;
   BYTE *curbuffer = (lol->offs_unread_CON) ?
-    (((BYTE*)lol) + lol->offs_unread_CON) : (BYTE*)NULL;
-  DOS_DEVICE_HEADER *con = (DOS_DEVICE_HEADER*)(((BYTE*)lol) + DEV1_OFS);
+    (((BYTE*)dataseg) + lol->offs_unread_CON) : (BYTE*)NULL;
+  DOS_DEVICE_HEADER *con = dataseg->dev;
   LPDOSTASK lpDosTask = MZ_Current();
 
   switch (hdr->command) {
@@ -429,50 +438,47 @@ Output of DOS 6.22:
 
 void DOSDEV_InstallDOSDevices(void)
 {
-  WINEDEV *dev;
-  DOS_DEVICE_HEADER *pdev;
+  DOS_DATASEG *dataseg;
   UINT16 seg;
   int n;
-  WORD ofs = DEV0_OFS;
-  DOS_LISTOFLISTS *DOS_LOL;
 
   /* allocate DOS data segment or something */
-  DOS_LOLSeg = GlobalDOSAlloc16(ALL_OFS+CON_BUFFER);
+  DOS_LOLSeg = GlobalDOSAlloc16(sizeof(DOS_DATASEG));
   seg = HIWORD(DOS_LOLSeg);
-  DOS_LOL = PTR_SEG_OFF_TO_LIN(LOWORD(DOS_LOLSeg), 0);
+  dataseg = PTR_SEG_OFF_TO_LIN(LOWORD(DOS_LOLSeg), 0);
 
   /* initialize the magnificent List Of Lists */
-  InitListOfLists(DOS_LOL);
-
-  /* copy first device (NUL) */
-  pdev = &(DOS_LOL->NUL_dev);
-  memcpy(pdev,&dev_nul_hdr,sizeof(DOS_DEVICE_HEADER));
-  pdev->strategy += ofs;
-  pdev->interrupt += ofs;
-  /* set up dev so we can copy over the rest */
-  dev = (WINEDEV*)(((char*)DOS_LOL)+ofs);
-  dev[0].ljmp1 = LJMP;
-  dev[0].strategy = (RMCBPROC)DPMI_AllocInternalRMCB(nul_strategy);
-  dev[0].ljmp2 = LJMP;
-  dev[0].interrupt = (RMCBPROC)DPMI_AllocInternalRMCB(nul_interrupt);
-
-  dev++;
-  ofs += sizeof(WINEDEV);
-
-  /* first of remaining devices is CON */
-  DOS_LOL->ptr_CON_dev_hdr = PTR_SEG_OFF_TO_SEGPTR(seg, ofs);
-
-  /* copy remaining devices */
-  memcpy(dev,&devs,sizeof(devs));
-  for (n=0; n<nr_devs; n++) {
-    pdev->next_dev = PTR_SEG_OFF_TO_SEGPTR(seg, ofs);
-    dev[n].hdr.strategy += ofs;
-    dev[n].hdr.interrupt += ofs;
-    dev[n].strategy = (RMCBPROC)DPMI_AllocInternalRMCB(dev[n].strategy);
-    dev[n].interrupt = (RMCBPROC)DPMI_AllocInternalRMCB(dev[n].interrupt);
-    ofs += sizeof(WINEDEV);
-    pdev = &(dev[n].hdr);
+  InitListOfLists(&dataseg->lol);
+
+  /* Set up first device (NUL) */
+  dataseg->lol.NUL_dev.next_dev  = PTR_SEG_OFF_TO_SEGPTR(seg, DOS_DATASEG_OFF(dev[0]));
+  dataseg->lol.NUL_dev.attr      = devs[0].attr;
+  dataseg->lol.NUL_dev.strategy  = DOS_DATASEG_OFF(thunk[0].ljmp1);
+  dataseg->lol.NUL_dev.interrupt = DOS_DATASEG_OFF(thunk[0].ljmp2);
+  memcpy(dataseg->lol.NUL_dev.name, devs[0].name, 8);
+
+  /* Set up the remaining devices */
+  for (n = 1; n < NR_DEVS; n++)
+  {
+    dataseg->dev[n-1].next_dev  = (n+1) == NR_DEVS ? NONEXT :
+                                  PTR_SEG_OFF_TO_SEGPTR(seg, DOS_DATASEG_OFF(dev[n]));
+    dataseg->dev[n-1].attr      = devs[n].attr;
+    dataseg->dev[n-1].strategy  = DOS_DATASEG_OFF(thunk[n].ljmp1);
+    dataseg->dev[n-1].interrupt = DOS_DATASEG_OFF(thunk[n].ljmp2);
+    memcpy(dataseg->dev[n-1].name, devs[n].name, 8);
   }
+
+  /* Set up thunks */
+  for (n = 0; n < NR_DEVS; n++)
+  {
+    dataseg->thunk[n].ljmp1     = LJMP;
+    dataseg->thunk[n].strategy  = (RMCBPROC)DPMI_AllocInternalRMCB(devs[n].strategy);
+    dataseg->thunk[n].ljmp2     = LJMP;
+    dataseg->thunk[n].interrupt = (RMCBPROC)DPMI_AllocInternalRMCB(devs[n].interrupt);
+  }
+
+  /* CON is device 1 */
+  dataseg->lol.ptr_CON_dev_hdr = PTR_SEG_OFF_TO_SEGPTR(seg, DOS_DATASEG_OFF(dev[0]));
 }
 
 DWORD DOSDEV_Console(void)
@@ -513,7 +519,7 @@ static void DOSDEV_DoReq(void*req, DWORD dev)
   char *phdr;
 
   dhdr = DOSMEM_MapRealToLinear(dev);
-  phdr = ((char*)DOSMEM_LOL()) + ALLDEV_OFS;
+  phdr = ((char*)DOSMEM_LOL()) + DOS_DATASEG_OFF(req);
 
   /* copy request to request scratch area */
   memcpy(phdr, req, hdr->size);
@@ -523,7 +529,7 @@ static void DOSDEV_DoReq(void*req, DWORD dev)
 
   /* ES:BX points to request for strategy routine */
   ES_reg(&ctx)  = HIWORD(DOS_LOLSeg);
-  EBX_reg(&ctx) = ALLDEV_OFS;
+  EBX_reg(&ctx) = DOS_DATASEG_OFF(req);
 
   /* call strategy routine */
   CS_reg(&ctx) = SELECTOROF(dev);
diff --git a/msdos/dosmem.c b/msdos/dosmem.c
index afdadca9ea885c012e7f25ca38f0909b0799142f..3967a39810221fd992edee27e5d785a7bbc81503 100644
--- a/msdos/dosmem.c
+++ b/msdos/dosmem.c
@@ -174,13 +174,14 @@ static void DOSMEM_FillBiosSegments(void)
     BIOSDATA *pBiosData = (BIOSDATA *)GlobalLock16( DOSMEM_BiosDataSeg );
 
     /* bogus 0xe0xx addresses !! Adapt int 0x10/0x1b if change needed */
-    BYTE *pVideoStaticFuncTable = pBiosSys+0xe000;
-    BYTE *pVideoStateInfo = pBiosSys+0xe010;
-    BYTE *p;
+    VIDEOFUNCTIONALITY *pVidFunc = (VIDEOFUNCTIONALITY *)(pBiosSys+0xe000);
+    VIDEOSTATE *pVidState = (VIDEOSTATE *)(pBiosSys+0xe010);
     int i;
 
       /* Clear all unused values */
     memset( pBiosData, 0, sizeof(*pBiosData) );
+    memset( pVidFunc,  0, sizeof(*pVidFunc ) );
+    memset( pVidState, 0, sizeof(*pVidState) );
 
     /* FIXME: should check the number of configured drives and ports */
 
@@ -210,7 +211,8 @@ static void DOSMEM_FillBiosSegments(void)
     pBiosData->DiskDataRate         = 0;
 
     /* fill ROM configuration table (values from Award) */
-    *(WORD *)(pBiosROMTable)= 0x08; /* number of bytes following */
+    *(pBiosROMTable+0x0)	= 0x08; /* number of bytes following LO */
+    *(pBiosROMTable+0x1)	= 0x00; /* number of bytes following HI */
     *(pBiosROMTable+0x2)	= 0xfc; /* model */
     *(pBiosROMTable+0x3)	= 0x01; /* submodel */
     *(pBiosROMTable+0x4)	= 0x00; /* BIOS revision */
@@ -220,59 +222,46 @@ static void DOSMEM_FillBiosSegments(void)
     *(pBiosROMTable+0x8)	= 0x00; /* feature byte 4 */
     *(pBiosROMTable+0x9)	= 0x00; /* feature byte 5 */
 
-    p = pVideoStaticFuncTable;
-    for (i=0; i < 7; i++)
-      *(p+i)  = 0xff; /* modes supported 1 to 7 */
     
-    *(p+0x7)  = 7;                  /* scan lines supported */
-    *(p+0x8)  = 0;                  /* tot nr of char blocks in text mode */
-    *(p+0x9)  = 0;                  /* max nr of active char blocks in text */
-    *(WORD *)(p+0xa) = 0x8ff;       /* misc support flags */
-    *(WORD *)(p+0xc) = 0;           /* reserved */
-    *(p+0xe)  = 0x3f;               /* save pointer function flags */  
-    *(p+0xf)  = 0;                  /* reserved */
-
-    p = pVideoStateInfo;
-    *(DWORD *)p = 0xf000e000;       /* address of pVideoStaticFuncTable, FIXME: always real mode ? */
-    *(p+0x04) =                     /* current video mode, needs updates ! */
-      pBiosData->VideoMode;
-    *(WORD *)(p+0x05) =             /* number of columns, needs updates ! */
-      pBiosData->VideoColumns;
-    *(WORD *)(p+0x07) = 0;          /* length of regen (???) buffer in bytes */
-    *(WORD *)(p+0x09) = 0;          /* starting address of regen (?) buffer */
-    *(WORD *)(p+0x0b) = 0;          /* cursorpos page 0 */
-    *(WORD *)(p+0x0d) = 0;          /* cursorpos page 1 */
-    *(WORD *)(p+0x0f) = 0;          /* page 2 */
-    *(WORD *)(p+0x11) = 0;          /* page 3 */
-    *(WORD *)(p+0x13) = 0;          /* page 4 */
-    *(WORD *)(p+0x15) = 0;          /* page 5 */
-    *(WORD *)(p+0x17) = 0;          /* page 6 */
-    *(WORD *)(p+0x19) = 0;          /* page 7 */
-    *(WORD *)(p+0x1b) = 0x0a0b;     /* cursor size (start/end line) */
-    *(p+0x1d) = 0;                  /* active display page */
-    *(WORD *)(p+0x1e) = 0x3da;      /* CRTC port address */
-    *(p+0x20) = 0x0;                /* current setting of port 0x3x8 */
-    *(p+0x21) = 0x0;                /* current setting of port 0x3x9 */
-    *(p+0x22) = 23;                 /* number of rows - 1 */
-    *(WORD *)(p+0x23) = 0x10;       /* bytes/character */
-    *(p+0x25) =                     /* comb. of active display */
-      pBiosData->DisplayCombination;
-    *(p+0x26) = 0;                  /* DCC (???) of alternate display */
-    *(WORD *)(p+0x27) = 16;         /* number of colors in current mode */
-    *(p+0x29) = 1;                  /* number of pages in current mode */
-    *(p+0x2a) = 3;                  /* number of scan lines active */
-                                    /* (0,1,2,3) =  (200,350,400,480) */
-    *(p+0x2b) = 0;                  /* primary character block (?) */
-    *(p+0x2c) = 0;                  /* secondary character block (?) */
-    *(p+0x2d) =                     /* miscellaneous flags */
-        (pBiosData->VGASettings & 0x0f)
-      | ((pBiosData->ModeOptions & 1) << 4); /* cursor emulation */
-    *(p+0x2e) = 0;                  /* non-VGA mode support */
-    *(WORD *)(p+0x2f) = 0;          /* reserved */
-    *(p+0x31) =                     /* video memory available */
-      (pBiosData->ModeOptions & 0x60 >> 5);
-    *(p+0x32) = 0;                  /* save pointer state flags */
-    *(p+0x33) = 4;                  /* display info and status */
+    for (i = 0; i < 7; i++)
+        pVidFunc->ModeSupport[i] = 0xff;
+    
+    pVidFunc->ScanlineSupport     = 7;
+    pVidFunc->NumberCharBlocks    = 0;
+    pVidFunc->ActiveCharBlocks    = 0;
+    pVidFunc->MiscFlags           = 0x8ff;
+    pVidFunc->SavePointerFlags    = 0x3f;
+
+    pVidState->StaticFuncTable    = 0xf000e000;  /* FIXME: always real mode ? */
+    pVidState->VideoMode          = pBiosData->VideoMode; /* needs updates! */
+    pVidState->NumberColumns      = pBiosData->VideoColumns; /* needs updates! */
+    pVidState->RegenBufLen        = 0;
+    pVidState->RegenBufAddr       = 0;
+
+    for (i = 0; i < 8; i++)
+        pVidState->CursorPos[i] = 0;
+
+    pVidState->CursorType         = 0x0a0b;  /* start/end line */
+    pVidState->ActivePage         = 0;
+    pVidState->CRTCPort           = 0x3da;
+    pVidState->Port3x8            = 0;
+    pVidState->Port3x9            = 0;
+    pVidState->NumberRows         = 23;     /* number of rows - 1 */
+    pVidState->BytesPerChar       = 0x10;
+    pVidState->DCCActive          = pBiosData->DisplayCombination;
+    pVidState->DCCAlternate       = 0;
+    pVidState->NumberColors       = 16;
+    pVidState->NumberPages        = 1;
+    pVidState->NumberScanlines    = 3; /* (0,1,2,3) = (200,350,400,480) */
+    pVidState->CharBlockPrimary   = 0;
+    pVidState->CharBlockSecondary = 0;
+    pVidState->MiscFlags =
+                           (pBiosData->VGASettings & 0x0f)
+                         | ((pBiosData->ModeOptions & 1) << 4); /* cursor emulation */
+    pVidState->NonVGASupport      = 0;
+    pVidState->VideoMem           = (pBiosData->ModeOptions & 0x60 >> 5);
+    pVidState->SavePointerState   = 0;
+    pVidState->DisplayStatus      = 4;
 
     /* BIOS date string */
     strcpy((char *)pBiosSys+0xfff5, "13/01/99");
diff --git a/msdos/dpmi.c b/msdos/dpmi.c
index 910ad607461fc040038705c48265c0123fa63309..0bd0898baabb77605d6cf9d51cc72d45d7962b8b 100644
--- a/msdos/dpmi.c
+++ b/msdos/dpmi.c
@@ -495,7 +495,7 @@ static RMCB *DPMI_AllocRMCB( void )
    the DPMI 0.9 spec states that if it doesn't, it will be called again */
 	*p++ = 0xeb;
 	*p++ = 0xfc; /* jmp RMCB */
-#else
+#elif defined(__i386__)
 	LPVOID RMCBmem = DOSMEM_GetBlock(0, 15, &uParagraph);
 	LPBYTE p = RMCBmem;
 
@@ -508,6 +508,8 @@ static RMCB *DPMI_AllocRMCB( void )
 	*(WORD *)p = __get_cs();
 	p+=2;
 	*p++=0xc3; /* lret (FIXME?) */
+#else
+	uParagraph = 0;
 #endif
 	NewRMCB->address = MAKELONG(0, uParagraph);
 	NewRMCB->next = FirstRMCB;