Index: /trunk/src/VBox/ValidationKit/bootsectors/Config.kmk
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/Config.kmk	(revision 60438)
+++ /trunk/src/VBox/ValidationKit/bootsectors/Config.kmk	(revision 60439)
@@ -53,4 +53,21 @@
 # The bs3kit source directory.
 VBOX_PATH_BS3KIT_SRC = $(VBOX_PATH_VALIDATIONKIT_SRC)/bootsectors/bs3kit
+
+
+# The 16-bit code & data segment classes.
+if 1
+BS3KIT_CLASS_CODE16 = CODE
+BS3KIT_SEGNM_DATA16 =
+BS3KIT_CLASS_DATA16 = DATA
+BS3KIT_GRPNM_DATA16 = DGROUP
+BS3KIT_CLASS_BSS16  = BSS
+else
+BS3KIT_CLASS_CODE16 = BS3CLASS16CODE
+BS3KIT_SEGNM_DATA16 = BS3DATA16
+BS3KIT_CLASS_DATA16 = FAR_DATA
+BS3KIT_GRPNM_DATA16 = BS3DATA16_GROUP
+BS3KIT_CLASS_BSS16  = ???
+endif
+
 
 # Dummy CP "linker" tool.
@@ -425,5 +442,5 @@
 #       -wx                    Maxium warning level.
 #       -zl                    Don't emit default library information.
-#       -zdp                   DS pegged to BS3DATA16_GROUP.
+#       -zdp                   DS pegged to BS3DATA16_GROUP/DGROUP.
 #       -zu                    Assume SS != DS.
 #       -mc                    Compact memory model, far data, small code.
@@ -453,5 +470,7 @@
 TEMPLATE_VBoxBS3KitImg_ASTOOL       = VBoxNasm
 TEMPLATE_VBoxBS3KitImg_ASFLAGS      = -f obj -g $(BS3KIT_NASM_allow_64_bit) -w+orphan-labels
-TEMPLATE_VBoxBS3KitImg_ASDEFS       = ASM_FORMAT_OMF RT_NOINC_SEGMENTS __NASM__ ARCH_BITS=16 RT_ARCH_X86
+TEMPLATE_VBoxBS3KitImg_ASDEFS       = ASM_FORMAT_OMF RT_NOINC_SEGMENTS __NASM__ ARCH_BITS=16 RT_ARCH_X86 \
+        BS3CLASS16CODE=$(BS3KIT_CLASS_CODE16) BS3KIT_CLASS_DATA16=$(BS3KIT_CLASS_DATA16) \
+	 BS3KIT_GRPNM_DATA16=$(BS3KIT_GRPNM_DATA16) BS3KIT_CLASS_BSS16=$(BS3KIT_CLASS_BSS16)
 TEMPLATE_VBoxBS3KitImg_DEFS         = IN_BS3KIT
 TEMPLATE_VBoxBS3KitImg_DEFS.debug   = BS3_STRICT
@@ -461,8 +480,8 @@
 TEMPLATE_VBoxBS3KitImg_CTOOL        = Bs3Ow16
 TEMPLATE_VBoxBS3KitImg_CXXTOOL      = Bs3Ow16
-TEMPLATE_VBoxBS3KitImg_CFLAGS       = \
-	-nt=BS3TEXT16 -nd=BS3DATA16 -nc=BS3CLASS16CODE -ecc -q -0 -wx -zl -zdp -zu -mc $(BS3_OW_DBG_OPT) -s -oa -ob -of -oi -ol -or -os -d+
-TEMPLATE_VBoxBS3KitImg_CXXFLAGS     = \
-	-nt=BS3TEXT16 -nd=BS3DATA16 -nc=BS3CLASS16CODE -ecc -q -0 -wx -zl -zdp -zu -mc $(BS3_OW_DBG_OPT) -s -oa -ob -of -oi -ol -or -os -d+
+TEMPLATE_VBoxBS3KitImg_CFLAGS       = $(if $(BS3KIT_SEGNM_DATA16),-nd=$(BS3KIT_SEGNM_DATA16),) \
+	-nt=BS3TEXT16 -nc=$(BS3KIT_CLASS_CODE16) -ecc -q -0 -wx -zl -zdp -zu -mc $(BS3_OW_DBG_OPT) -s -oa -ob -of -oi -ol -or -os -d+
+TEMPLATE_VBoxBS3KitImg_CXXFLAGS     = $(if $(BS3KIT_SEGNM_DATA16),-nd=$(BS3KIT_SEGNM_DATA16),) \
+	-nt=BS3TEXT16 -nc=$(BS3KIT_CLASS_CODE16) -ecc -q -0 -wx -zl -zdp -zu -mc $(BS3_OW_DBG_OPT) -s -oa -ob -of -oi -ol -or -os -d+
 TEMPLATE_VBoxBS3KitImg_CDEFS        = ARCH_BITS=16 RT_ARCH_X86
 
@@ -509,33 +528,51 @@
  	 clname BS3FLAT segaddr=0x0000 \
  	   segment BS3FLAT segaddr=0x0000 \
- 	 clname BS3CLASS16CODE segaddr=0x1000 \
+ 	 clname $(BS3KIT_CLASS_CODE16) segaddr=0x1000 \
  	  segment BS3TEXT16 \
  	  segment BS3TEXT16_END \
         clname BS3SYSTEM16 segaddr=0x2000 \
          segment BS3SYSTEM16 \
+$(if-expr "$(BS3KIT_SEGNM_DATA16)" == "", \
+ 	 clname DATA \
+ 	  segment BS3DATA16 segaddr=0x2900 \
+ 	  segment BS3DATA16_DATA \
+ 	  segment DATA \
+ 	  segment _DATA \
+ 	  segment BS3DATA16CONST \
+ 	  segment CONST \
+ 	  segment BS3DATA16CONST2 \
+ 	  segment CONST2 \
+ 	  segment STRINGS \
+ 	  segment BS3DATA16_END \
+        clname BSS \
+ 	  segment BSS \
+ 	  segment _BSS \
+ 	  segment BS3DATA16_END \
+ 	 clname FAR_DATA \
+         segment FAR_DATA \
+, \
  	 clname FAR_DATA \
  	  segment BS3DATA16 segaddr=0x2900 \
+         segment FAR_DATA \
  	  segment BS3DATA16CONST \
  	  segment BS3DATA16CONST2 \
  	  segment BS3DATA16_DATA \
  	  segment BS3DATA16_END \
+) \
 	  segment BS3DATA32 \
 	  segment BS3DATA32CONST \
 	  segment BS3DATA32CONST2 \
 	  segment BS3DATA32_DATA \
- 	  segment DATA32 \
+	  segment BS3DATA32_BSS \
 	  segment BS3DATA32_END \
+         \
  	  segment BS3DATA64 \
- 	  segment DATA64 \
- 	  segment .data \
- 	  segment DATA64_END \
+ 	  segment BS3DATA64CONST \
+ 	  segment BS3DATA64_BSS \
+ 	  segment BS3DATA64_END \
         clname BS3CLASS32CODE \
  	  segment BS3TEXT32 \
- 	  segment TEXT32 \
         clname BS3CLASS64CODE \
- 	  segment BS3TEXT64 \
- 	  segment TEXT64 \
- 	  segment .text \
- 	  segment .rdata \
+ 	  segment BS3TEXT64
 
 TEMPLATE_VBoxBS3KitImg_LNK_DEPS = \
@@ -583,5 +620,7 @@
 TEMPLATE_VBoxBS3KitImg32_ASOBJSUFF    = .o32
 TEMPLATE_VBoxBS3KitImg32_ASFLAGS      = -f obj -g $(BS3KIT_NASM_allow_64_bit) -w+orphan-labels
-TEMPLATE_VBoxBS3KitImg32_ASDEFS       = ASM_FORMAT_OMF RT_NOINC_SEGMENTS __NASM__
+TEMPLATE_VBoxBS3KitImg32_ASDEFS       = ASM_FORMAT_OMF RT_NOINC_SEGMENTS __NASM__ \
+        BS3CLASS16CODE=$(BS3KIT_CLASS_CODE16) BS3KIT_CLASS_DATA16=$(BS3KIT_CLASS_DATA16) \
+	 BS3KIT_GRPNM_DATA16=$(BS3KIT_GRPNM_DATA16) BS3KIT_CLASS_BSS16=$(BS3KIT_CLASS_BSS16)
 TEMPLATE_VBoxBS3KitImg32_DEFS         = ARCH_BITS=32 IN_BS3KIT
 TEMPLATE_VBoxBS3KitImg32_DEFS.debug   = BS3_STRICT
@@ -604,5 +643,7 @@
 TEMPLATE_VBoxBS3KitImg64_ASOBJSUFF    = .o64
 TEMPLATE_VBoxBS3KitImg64_ASFLAGS      = -f obj -g $(BS3KIT_NASM_allow_64_bit) -w+orphan-labels
-TEMPLATE_VBoxBS3KitImg64_ASDEFS       = ASM_FORMAT_OMF ASM_CALL64_MSC RT_NOINC_SEGMENTS __NASM__
+TEMPLATE_VBoxBS3KitImg64_ASDEFS       = ASM_FORMAT_OMF ASM_CALL64_MSC RT_NOINC_SEGMENTS __NASM__ \
+        BS3CLASS16CODE=$(BS3KIT_CLASS_CODE16) BS3KIT_CLASS_DATA16=$(BS3KIT_CLASS_DATA16) \
+	 BS3KIT_GRPNM_DATA16=$(BS3KIT_GRPNM_DATA16) BS3KIT_CLASS_BSS16=$(BS3KIT_CLASS_BSS16)
 TEMPLATE_VBoxBS3KitImg64_DEFS         = IN_BS3KIT ARCH_BITS=64
 TEMPLATE_VBoxBS3KitImg64_DEFS.debug   = BS3_STRICT
@@ -636,6 +677,99 @@
 TEMPLATE_VBoxBS3KitBS_ASTOOL          = YASM
 TEMPLATE_VBoxBS3KitBS_ASFLAGS         = -f bin --mapfile
-TEMPLATE_VBoxBS3KitBS_ASDEFS          = ASM_FORMAT_BIN RT_NOINC_SEGMENTS ARCH_BITS=16 __YASM__
+TEMPLATE_VBoxBS3KitBS_ASDEFS          = ASM_FORMAT_BIN RT_NOINC_SEGMENTS ARCH_BITS=16 __YASM__ \
+        BS3CLASS16CODE=$(BS3KIT_CLASS_CODE16) BS3KIT_CLASS_DATA16=$(BS3KIT_CLASS_DATA16) \
+	 BS3KIT_GRPNM_DATA16=$(BS3KIT_GRPNM_DATA16) BS3KIT_CLASS_BSS16=$(BS3KIT_CLASS_BSS16)
 TEMPLATE_VBoxBS3KitBS_INCS            = $(VBOX_PATH_BS3KIT_SRC) .
 TEMPLATE_VBoxBS3KitBS_LDTOOL          = VBoxBsCpLd
 
+
+
+#
+# Extends VBoxBS3KitImg
+# User must starts SOURCES with: $(VBOX_PATH_BS3KIT_SRC)/bs3-first-dosexe.asm
+##       disable 1014, 1080, 1150
+#
+TEMPLATE_VBoxBS3KitUtil = Utility using bs3kit code.
+TEMPLATE_VBoxBS3KitUtil_EXTENDS  = VBoxBS3KitImg
+TEMPLATE_VBoxBS3KitUtil_BINSUFF  = .exe
+TEMPLATE_VBoxBS3KitUtil_DEFS     = $(TEMPLATE_VBoxBS3KitImg_DEFS) BS3_IS_DOS_EXE
+TEMPLATE_VBoxBS3KitUtil_CFLAGS   = $(filter-out -zl,$(TEMPLATE_VBoxBS3KitImg_CFLAGS))
+TEMPLATE_VBoxBS3KitUtil_CXXFLAGS = $(filter-out -zl,$(TEMPLATE_VBoxBS3KitImg_CXXFLAGS))
+TEMPLATE_VBoxBS3KitUtil_LDFLAGS  = system dos \
+	debug $(BS3_OW_DBG_LDOPT) all \
+	option quiet, map, statics, verbose, symfile \
+       disable 1080 \
+ 	order \
+ 	 clname $(BS3KIT_CLASS_CODE16) \
+ 	  segment BEGTEXT \
+ 	  segment BS3TEXT16 \
+ 	  segment _TEXT \
+ 	  segment BS3TEXT16_END \
+        clname BS3SYSTEM16  \
+         segment BS3SYSTEM16 \
+         \
+ 	 clname BEGDATA \
+ 	  segment _NULL  \
+ 	  segment _AFTERNULL  \
+ 	 clname DATA \
+$(if-expr "$(BS3KIT_SEGNM_DATA16)" == "", \
+ 	  segment BS3DATA16 \
+ 	  segment BS3DATA16CONST \
+ 	  segment CONST \
+ 	  segment BS3DATA16CONST2 \
+ 	  segment CONST2 \
+,\
+ 	  segment CONST \
+ 	  segment CONST2 \
+) \
+ 	  segment _DATA  \
+ 	  segment XIB  \
+ 	  segment XI  \
+ 	  segment XIE  \
+ 	  segment YIB  \
+ 	  segment YI  \
+ 	  segment YIE  \
+ 	  segment STRINGS  \
+$(if-expr "$(BS3KIT_SEGNM_DATA16)" == "", \
+ 	  segment BS3DATA16_DATA \
+,) \
+ 	  segment DATA  \
+ 	 clname BSS \
+	  segment _BSS \
+	  segment BSS \
+ 	  segment BS3DATA16_END \
+ 	 clname STACK \
+ 	  segment STACK \
+         \
+ 	 clname FAR_DATA \
+$(if-expr "$(BS3KIT_SEGNM_DATA16)" != "", \
+ 	  segment BS3DATA16  \
+ 	  segment BS3DATA16_DATA \
+ 	  segment BS3DATA16CONST \
+ 	  segment BS3DATA16CONST2 \
+ 	  segment FAR_DATA \
+ 	  segment BS3DATA16_END \
+,\
+ 	  segment FAR_DATA \
+)\
+	  segment BS3DATA32 \
+	  segment BS3DATA32CONST \
+	  segment BS3DATA32CONST2 \
+	  segment BS3DATA32_DATA \
+	  segment BS3DATA32_BSS \
+	  segment BS3DATA32_END \
+         \
+ 	  segment BS3DATA64 \
+ 	  segment BS3DATA64CONST \
+ 	  segment BS3DATA64_BSS \
+ 	  segment BS3DATA64_END \
+        clname BS3CLASS32CODE \
+ 	  segment BS3TEXT32 \
+        clname BS3CLASS64CODE \
+ 	  segment BS3TEXT64
+# 	 clname BS3FLAT segaddr=0x0000 \
+# 	   segment BS3FLAT segaddr=0x0000
+
+TEMPLATE_VBoxBS3KitUtil_LNK_DEPS  = $(NO_SUCH_VARIABLE)
+TEMPLATE_VBoxBS3KitUtil_POST_CMDS = $(NO_SUCH_VARIABLE)
+
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk	(revision 60438)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk	(revision 60439)
@@ -39,4 +39,5 @@
 BLDPROGS += VBoxBs3ObjConverter
 VBoxBs3ObjConverter_TEMPLATE = VBoxAdvBldProg
+VBoxBs3ObjConverter_DEFS     =  BS3KIT_BS3CLASS16CODE=$(BS3KIT_BS3CLASS16CODE)
 VBoxBs3ObjConverter_SOURCES  = $(VBOX_PATH_BS3KIT_SRC)/VBoxBs3ObjConverter.cpp
 
@@ -416,4 +417,14 @@
 
 
+#
+# DOS Utilities / Testcases.
+#
+MISCBINS += bs3cpudt
+bs3cpudt_TEMPLATE = VBoxBS3KitUtil
+bs3cpudt_SOURCES  = \
+	bs3-first-dosexe.asm \
+	bs3cpudt.c
+
+
 include $(FILE_KBUILD_SUB_FOOTER)
 
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-c16-Trap16Generic.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-c16-Trap16Generic.asm	(revision 60438)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-c16-Trap16Generic.asm	(revision 60439)
@@ -248,5 +248,5 @@
         mov     [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rbp], dx
 
-        mov     dl, [bp + 4]
+        mov     dl, [bp + 2]
         mov     [ss:bx + BS3TRAPFRAME.bXcpt], dl
 
@@ -299,4 +299,6 @@
         mov     [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rdi], edi
         mov     [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rsi], esi
+        mov     [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.fs], fs
+        mov     [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.gs], gs
         jmp     .save_segment_registers
 .save_word_grps:
@@ -308,6 +310,4 @@
         mov     [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.ds], ds
         mov     [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.es], es
-        mov     [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.fs], fs
-        mov     [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.gs], gs
 
         ;
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-PrintStrN.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-PrintStrN.asm	(revision 60438)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-PrintStrN.asm	(revision 60439)
@@ -152,4 +152,5 @@
 ;
 BS3_PROC_BEGIN Bs3PrintStrN_c16_CX_Bytes_At_DS_SI
+        CPU 8086
         ; Check if CX is zero first.
         test    cx, cx
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-RegCtxRestore.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-RegCtxRestore.asm	(revision 60438)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-RegCtxRestore.asm	(revision 60439)
@@ -50,4 +50,5 @@
 BS3_PROC_BEGIN_CMN Bs3RegCtxRestore_aborts ; special entry point for when watcom applies __aborts
  %if TMPL_BITS == 16
+        CPU 8086
         xor     xAX, xAX
         push    xAX                     ; fake return address.
@@ -84,9 +85,9 @@
 
         ;
-        ; Prologue.  Loads ES with BS3DATA16/FLAT (for g_bBs3CurrentMode and
-        ; g_uBs3CpuDetected), DS:xBX with pRegCtx and fFlags into xCX.
+        ; Prologue.  Loads ES with BS3KIT_GRPNM_DATA16/FLAT (for g_bBs3CurrentMode
+        ; and g_uBs3CpuDetected), DS:xBX with pRegCtx and fFlags into xCX.
         ;
 %if TMPL_BITS == 16
-        mov     ax, BS3DATA16
+        mov     ax, BS3_SEL_DATA16
         mov     es, ax
         lds     bx, [bp + 4]
@@ -127,4 +128,5 @@
         cmp     byte [es:BS3_DATA16_WRT(g_uBs3CpuDetected)], BS3CPU_80286
         jb      .restore_16_bit_ancient
+        CPU 286
 
         lmsw    [bx + BS3REGCTX.cr0]
@@ -132,7 +134,28 @@
         je      .restore_16_bit_ancient
         lldt    [bx + BS3REGCTX.ldtr]
+
+        ; TR - complicated because we need to clear the busy bit. ASSUMES GDT.
+        str     ax
+        cmp     ax, [bx + BS3REGCTX.tr]
+        je      .skip_tr_286
+
+        mov     di, word [xBX + BS3REGCTX.tr]
+        or      di, di                  ; check for null.
+        jz      .load_tr_286
+
+        push    ds
+        push    BS3_SEL_SYSTEM16
+        pop     ds
+        add     di, Bs3Gdt wrt BS3SYSTEM16
+        add     di, X86DESCGENERIC_BIT_OFF_TYPE / 8
+        and     byte [di], ~(X86_SEL_TYPE_SYS_TSS_BUSY_MASK << (X86DESCGENERIC_BIT_OFF_TYPE % 8))
+        pop     ds
+
+.load_tr_286:
         ltr     [bx + BS3REGCTX.tr]
+.skip_tr_286:
 
 .restore_16_bit_ancient:
+        CPU 8086
         ; Some general registers.
         mov     cx, [bx + BS3REGCTX.rcx]
@@ -198,6 +221,7 @@
         pop     bp
         iret
-%endif
-
+
+        CPU 386
+%endif
 
 .restore_full:
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-RegCtxSave.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-RegCtxSave.asm	(revision 60438)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-RegCtxSave.asm	(revision 60439)
@@ -44,4 +44,5 @@
 ;
 BS3_PROC_BEGIN_CMN Bs3RegCtxSave
+        TMPL_ONLY_16BIT_STMT CPU 8086
         BS3_CALL_CONV_PROLOG 1
         push    xBP
@@ -56,5 +57,5 @@
         ;
         ; Prologue. Load ES:xDI with pRegCtx.
-        ; (ASSUMES ds is BS3DATA16/FLAT of course.)
+        ; (ASSUMES ds is BS3KIT_GRPNM_DATA16/FLAT of course.)
         ;
 %if TMPL_BITS == 16
@@ -111,7 +112,10 @@
         cmp     cl, BS3CPU_80286
         jb      .common_ancient
+        CPU 286
 
         smsw    [xDI + BS3REGCTX.cr0]
         jmp     .common_80286
+
+        CPU 386
 %endif
 
@@ -196,4 +200,5 @@
         ; 80286 control registers.
 .common_80286:
+        TMPL_ONLY_16BIT_STMT CPU 286
         str     [xDI + BS3REGCTX.tr]
         sldt    [xDI + BS3REGCTX.ldtr]
@@ -201,4 +206,5 @@
         ; Common stuff - stuff on the stack, 286 segment registers.
 .common_ancient:
+        TMPL_ONLY_16BIT_STMT CPU 8086
         mov     xAX, [xBP - xCB*1]
         mov     [xDI + BS3REGCTX.rflags], xAX
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-SwitchTo16BitV86.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-SwitchTo16BitV86.asm	(revision 60438)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-SwitchTo16BitV86.asm	(revision 60439)
@@ -78,5 +78,5 @@
 
 .not_v8086:
-        pop     ax                      ; Drop the push ds so the stacks are identical. Keep DS = BS3DATA16 though.
+        pop     ax                      ; Drop the push ds so the stacks are identical. Keep DS = BS3KIT_GRPNM_DATA16 though.
  %endif
 
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-TestFailed.c
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-TestFailed.c	(revision 60438)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-TestFailed.c	(revision 60439)
@@ -40,5 +40,5 @@
 BS3_DECL_CALLBACK(size_t) bs3TestFailedStrOutput(char ch, void BS3_FAR *pvUser)
 {
-    bool *pfNewLine = (bool *)pvUser;
+    PBS3TESTFAILEDBUF pBuf = (PBS3TESTFAILEDBUF)pvUser;
 
     /*
@@ -48,6 +48,7 @@
     if (g_fbBs3VMMDevTesting)
     {
-        if (*pfNewLine && ch != '\0')
+        if (pBuf->fNewLine && ch != '\0')
             ASMOutU8(VMMDEV_TESTING_IOPORT_DATA, '\n');
+        pBuf->fNewLine = ch == '\n';
         if (ch != '\n')
             ASMOutU8(VMMDEV_TESTING_IOPORT_DATA, ch);
@@ -57,15 +58,35 @@
      * Console next.
      */
-    if (ch != 0)
+    if (ch != '\0')
     {
-        Bs3PrintChr(ch);
-        *pfNewLine = ch == '\n';
+        BS3_ASSERT(pBuf->cchBuf < RT_ELEMENTS(pBuf->achBuf));
+        pBuf->achBuf[pBuf->cchBuf++] = ch;
+
+        /* Whether to flush the buffer.  We do line flushing here to avoid
+           dropping too much info when the formatter crashes on bad input. */
+        if (   pBuf->cchBuf < RT_ELEMENTS(pBuf->achBuf)
+            && ch != '\n')
+        {
+            pBuf->fNewLine = false;
+            return 1;
+        }
+        pBuf->fNewLine = '\n';
     }
-    /* We're called with '\0' to indicate end-of-string. Supply trailing
-       newline if necessary. */
-    else if (!*pfNewLine)
+    /* Try fit missing newline into the buffer. */
+    else if (!pBuf->fNewLine && pBuf->cchBuf < RT_ELEMENTS(pBuf->achBuf))
+    {
+        pBuf->fNewLine = true;
+        pBuf->achBuf[pBuf->cchBuf++] = '\n';
+    }
+
+    BS3_ASSERT(pBuf->cchBuf <= RT_ELEMENTS(pBuf->achBuf));
+    Bs3PrintStrN(&pBuf->achBuf[0], pBuf->cchBuf);
+    pBuf->cchBuf = 0;
+
+    /* In case we failed to add trailing new line, print one separately.  */
+    if (!pBuf->fNewLine)
         Bs3PrintChr('\n');
 
-    return 1;
+    return ch != '\0';
 }
 
@@ -76,5 +97,5 @@
 BS3_DECL(void) Bs3TestFailedV(const char *pszFormat, va_list va)
 {
-    bool fNewLine;
+    BS3TESTFAILEDBUF Buf;
 
     if (!++g_cusBs3TestErrors)
@@ -82,8 +103,13 @@
 
     if (g_fbBs3VMMDevTesting)
+#if ARCH_BITS == 16
+        ASMOutU16(VMMDEV_TESTING_IOPORT_CMD, (uint16_t)VMMDEV_TESTING_CMD_FAILED);
+#else
         ASMOutU32(VMMDEV_TESTING_IOPORT_CMD, VMMDEV_TESTING_CMD_FAILED);
+#endif
 
-    fNewLine = false;
-    Bs3StrFormatV(pszFormat, va, bs3TestFailedStrOutput, &fNewLine);
+    Buf.fNewLine = false;
+    Buf.cchBuf   = 0;
+    Bs3StrFormatV(pszFormat, va, bs3TestFailedStrOutput, &Buf);
 }
 
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-TestPrintf.c
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-TestPrintf.c	(revision 60438)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-TestPrintf.c	(revision 60439)
@@ -36,4 +36,10 @@
 
 /*********************************************************************************************************************************
+*   Defined Constants And Macros                                                                                                 *
+*********************************************************************************************************************************/
+#define SMALL_BUFFER 1
+
+
+/*********************************************************************************************************************************
 *   Structures and Typedefs                                                                                                      *
 *********************************************************************************************************************************/
@@ -41,7 +47,12 @@
 typedef struct BS3TESTPRINTBUF
 {
-    bool    fNewCmd;
-    uint8_t cchBuf;
-    char    achBuf[78];
+    bool     fNewCmd;
+#if SMALL_BUFFER
+    uint8_t  cchBuf;
+    char     achBuf[78];
+#else
+    uint16_t cchBuf;
+    char     achBuf[512];
+#endif
 } BS3TESTPRINTBUF;
 
@@ -66,5 +77,9 @@
             if (pBuf->fNewCmd)
             {
+#if ARCH_BITS == 16
+                ASMOutU16(VMMDEV_TESTING_IOPORT_CMD, (uint16_t)VMMDEV_TESTING_CMD_PRINT);
+#else
                 ASMOutU32(VMMDEV_TESTING_IOPORT_CMD, VMMDEV_TESTING_CMD_PRINT);
+#endif
                 pBuf->fNewCmd = false;
             }
@@ -89,5 +104,5 @@
            dropping too much info when the formatter crashes on bad input. */
         if (   pBuf->cchBuf < RT_ELEMENTS(pBuf->achBuf)
-            && ch != '\n')
+            && (!SMALL_BUFFER || ch != '\n') )
             return 1;
     }
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-TestSendCmdWithStr.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-TestSendCmdWithStr.asm	(revision 60438)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-TestSendCmdWithStr.asm	(revision 60439)
@@ -43,6 +43,4 @@
         BS3_ONLY_16BIT_STMT push ds
 
-        mov     ax, seg g_fbBs3VMMDevTesting
-        mov     ds, ax
         cmp     byte [BS3_DATA16_WRT(g_fbBs3VMMDevTesting)], 0
         je      .no_vmmdev
@@ -50,10 +48,15 @@
         ; The command (uCmd).
         mov     dx, VMMDEV_TESTING_IOPORT_CMD
+%if TMPL_BITS == 16
+        mov     ax, [xBP + xCB*2]       ; We ignore the top bits in 16-bit mode.
+        out     dx, ax
+%else
         mov     eax, [xBP + xCB*2]
         out     dx, eax
+%endif
 
         ; The string.
         mov     dx, VMMDEV_TESTING_IOPORT_DATA
-%ifdef TMPL_16BIT
+%if TMPL_BITS == 16
         lds     si, [xBP + xCB*2 + sCB]
 %else
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-TestSendCmdWithU32.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-TestSendCmdWithU32.asm	(revision 60438)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-TestSendCmdWithU32.asm	(revision 60439)
@@ -42,21 +42,33 @@
         push    xSI
 
-        BS3_ONLY_16BIT_STMT push ds
-        mov     ax, seg g_fbBs3VMMDevTesting
-        mov     ds, ax
         cmp     byte [BS3_DATA16_WRT(g_fbBs3VMMDevTesting)], 0
-        BS3_ONLY_16BIT_STMT pop  ds
         je      .no_vmmdev
 
-        ; The command (uCmd).
+        ; The command (uCmd) -
         mov     dx, VMMDEV_TESTING_IOPORT_CMD
+%if TMPL_BITS == 16
+        mov     ax, [xBP + xCB*2]       ; We ignore the top bits in 16-bit mode.
+        out     dx, ax
+%else
         mov     eax, [xBP + xCB*2]
         out     dx, eax
+%endif
+
 
         ; The value (uValue).
         mov     dx, VMMDEV_TESTING_IOPORT_DATA
+%if TMPL_BITS == 16
+        mov     ax, [xBP + xCB*2 + sCB]
+        out     dx, ax
+        mov     ax, [xBP + xCB*2 + sCB + 2]
+        out     dx, ax
+%else
         mov     eax, [xBP + xCB*2 + sCB]
         out     dx, eax
+%endif
 
+%if TMPL_BITS == 16
+        pop     sAX
+%endif
 .no_vmmdev:
         pop     xSI
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-TestSkipped.c
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-TestSkipped.c	(revision 60438)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-TestSkipped.c	(revision 60439)
@@ -46,11 +46,17 @@
         /* Tell VMMDev */
         if (g_fbBs3VMMDevTesting)
+#if ARCH_BITS == 16
+            ASMOutU16(VMMDEV_TESTING_IOPORT_CMD, (uint16_t)VMMDEV_TESTING_CMD_SKIPPED);
+#else
             ASMOutU32(VMMDEV_TESTING_IOPORT_CMD, VMMDEV_TESTING_CMD_SKIPPED);
+#endif
 
         /* The reason why it was skipped is optional. */
         if (pszFormat)
         {
-            bool fNewLine = false;
-            Bs3StrFormatV(pszFormat, va, bs3TestFailedStrOutput, &fNewLine);
+            BS3TESTFAILEDBUF Buf;
+            Buf.fNewLine = false;
+            Buf.cchBuf   = 0;
+            Bs3StrFormatV(pszFormat, va, bs3TestFailedStrOutput, &Buf);
         }
         else if (g_fbBs3VMMDevTesting)
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-TrapPrintFrame.c
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-TrapPrintFrame.c	(revision 60438)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-TrapPrintFrame.c	(revision 60439)
@@ -33,4 +33,5 @@
 BS3_DECL(void) Bs3TrapPrintFrame(PCBS3TRAPFRAME pTrapFrame)
 {
+#if 1
     Bs3TestPrintf("Trap %#04x errcd=%#06RX64 at %04x:%016RX64 - test step %d (%#x)\n",
                   pTrapFrame->bXcpt,
@@ -40,4 +41,30 @@
                   g_usBs3TestStep, g_usBs3TestStep);
     Bs3RegCtxPrint(&pTrapFrame->Ctx);
+#else
+    /* This is useful if having trouble returning from real mode. */
+    PCBS3REGCTX pRegCtx = &pTrapFrame->Ctx;
+    Bs3TestPrintf("Trap %#04x errcd=%#06RX64 at %04x:%016RX64 - test step %d (%#x)\n"
+                  "eax=%08RX32 ebx=%08RX32 ecx=%08RX32 edx=%08RX32 esi=%08RX32 edi=%08RX32\n"
+                  "eip=%08RX32 esp=%08RX32 ebp=%08RX32 efl=%08RX32 cr0=%08RX32 cr2=%08RX32\n"
+                  "cs=%04RX16   ds=%04RX16 es=%04RX16 fs=%04RX16 gs=%04RX16   ss=%04RX16 cr3=%08RX32 cr4=%08RX32\n"
+                  "tr=%04RX16 ldtr=%04RX16 cpl=%d   mode=%#x fbFlags=%#x\n"
+                  ,
+                  pTrapFrame->bXcpt,
+                  pTrapFrame->uErrCd,
+                  pTrapFrame->Ctx.cs,
+                  pTrapFrame->Ctx.rip.u64,
+                  g_usBs3TestStep, g_usBs3TestStep
+                  ,
+                  pRegCtx->rax.u32, pRegCtx->rbx.u32, pRegCtx->rcx.u32, pRegCtx->rdx.u32, pRegCtx->rsi.u32, pRegCtx->rdi.u32
+                  ,
+                  pRegCtx->rip.u32, pRegCtx->rsp.u32, pRegCtx->rbp.u32, pRegCtx->rflags.u32,
+                  pRegCtx->cr0.u32, pRegCtx->cr2.u32
+                  ,
+                  pRegCtx->cs, pRegCtx->ds, pRegCtx->es, pRegCtx->fs, pRegCtx->gs, pRegCtx->ss,
+                  pRegCtx->cr3.u32, pRegCtx->cr4.u32
+                  ,
+                  pRegCtx->tr, pRegCtx->ldtr, pRegCtx->bCpl, pRegCtx->bMode, pRegCtx->fbFlags);
+
+#endif
 }
 
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-test.h
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-test.h	(revision 60438)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-test.h	(revision 60439)
@@ -141,5 +141,5 @@
  *      Used by Bs3TestFailedV and Bs3TestSkippedV.
  *
- *      The @a pvUser parameter must point to a boolean that was initialized to false. }
+ *      The @a pvUser parameter must point a BS3TESTFAILEDBUF structure. }
  */
 BS3_DECL_CALLBACK(size_t) bs3TestFailedStrOutput_c16(char ch, void BS3_FAR *pvUser);
@@ -148,4 +148,19 @@
 #define bs3TestFailedStrOutput BS3_CMN_NM(bs3TestFailedStrOutput) /**< Selects #bs3TestFailedStrOutput_c16, #bs3TestFailedStrOutput_c32 or #bs3TestFailedStrOutput_c64. */
 
+/**
+ * Output buffering for bs3TestFailedStrOutput.
+ */
+typedef struct BS3TESTFAILEDBUF
+{
+    /** Initialize to false. */
+    bool    fNewLine;
+    /** Initialize to zero. */
+    uint8_t cchBuf;
+    /** Buffer, uninitialized. */
+    char    achBuf[128];
+} BS3TESTFAILEDBUF;
+/** Pointer to a bs3TestFailedStrOutput buffer.  */
+typedef BS3TESTFAILEDBUF BS3_FAR *PBS3TESTFAILEDBUF;
+
 #endif
 
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-first-common.mac
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-first-common.mac	(revision 60438)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-first-common.mac	(revision 60439)
@@ -39,13 +39,27 @@
 ; 16-bit text
 ;
-BS3_BEGIN_TEXT16
+%ifndef BS3_IS_DOS_EXE
+BS3_BEGIN_TEXT16
+%else
+section BEGTEXT align=2 CLASS=BS3CLASS16CODE PUBLIC USE16
+BS3_BEGIN_TEXT16
+section BEGTEXT
+%endif
 BS3_GLOBAL_DATA Bs3Text16_StartOfSegment, 0
 
 ; Entry point with eye-catcher.
 GLOBALNAME start
-global __ImageBase                      ; for MS compiler
+global __ImageBase                      ; for MS compiler - must be first!
 __ImageBase:
+global ___begtext                       ; for DOS EXEs (causes harmless duplicate symbol warning)
+___begtext:
+%ifndef BS3_IS_DOS_EXE
     jmp     .after_eye_catcher
+%else
+    int3
+    jmp     __ImageBase
+%endif
     db      10,13,'eye-catcher: BS3TEXT16',10,13
+BS3_BEGIN_TEXT16
 .after_eye_catcher:
 
@@ -53,4 +67,5 @@
 section BS3TEXT16_END   align=2 progbits alloc exec nowrite
 %else
+section _TEXT           align=2 CLASS=BS3CLASS16CODE PUBLIC USE16
 section BS3TEXT16_END   align=2 CLASS=BS3CLASS16CODE PUBLIC USE16
 %endif
@@ -59,5 +74,9 @@
 
 %ifndef ASM_FORMAT_ELF
+ %ifndef BS3_IS_DOS_EXE
 GROUP CGROUP16 BS3TEXT16 BS3TEXT16_END
+ %else
+GROUP CGROUP16 BEGTEXT BS3TEXT16 _TEXT BS3TEXT16_END
+ %endif
 %endif
 
@@ -66,4 +85,5 @@
 ; 16-bit data
 ;
+%define BS3_BEGIN_DATA16_WITHOUT_GROUP
 BS3_BEGIN_DATA16
 BS3_GLOBAL_DATA Bs3Data16_StartOfSegment, 0
@@ -72,7 +92,7 @@
 ALIGNDATA(16)
 BS3_GLOBAL_DATA Bs3Data16_Size, 4
-    dd  BS3_DATA_NM(Bs3Data16_EndOfSegment) wrt BS3DATA16_GROUP
+    dd  BS3_DATA_NM(Bs3Data16_EndOfSegment) wrt BS3KIT_GRPNM_DATA16
 BS3_GLOBAL_DATA Bs3Data16Thru64Text32And64_TotalSize, 4
-    dd  BS3_DATA_NM(Bs3Data64_EndOfSegment) wrt BS3DATA16_GROUP
+    dd  BS3_DATA_NM(Bs3Data64_EndOfSegment) wrt BS3KIT_GRPNM_DATA16
 BS3_GLOBAL_DATA Bs3TotalImageSize, 4
     dd  BS3_DATA_NM(Bs3Data64_EndOfSegment) wrt CGROUP16
@@ -86,8 +106,30 @@
 section BS3DATA16_END   align=2   progbits alloc noexec write
 %else
-section BS3DATA16CONST  align=2   CLASS=FAR_DATA PUBLIC USE16
-section BS3DATA16CONST2 align=2   CLASS=FAR_DATA PUBLIC USE16
-section BS3DATA16_DATA  align=2   CLASS=FAR_DATA PUBLIC USE16
-section BS3DATA16_END   align=2   CLASS=FAR_DATA PUBLIC USE16
+section BS3DATA16CONST  align=2   CLASS=BS3KIT_CLASS_DATA16 PUBLIC USE16
+section BS3DATA16CONST2 align=2   CLASS=BS3KIT_CLASS_DATA16 PUBLIC USE16
+section BS3DATA16_DATA  align=2   CLASS=BS3KIT_CLASS_DATA16 PUBLIC USE16
+ %ifdef BS3_IS_DOS_EXE
+section _NULL           align=16  CLASS=BEGDATA  PUBLIC USE16
+section _AFTERNULL      align=2   CLASS=BEGDATA  PUBLIC USE16
+ %endif
+section CONST           align=2   CLASS=DATA     PUBLIC USE16
+section CONST2          align=2   CLASS=DATA     PUBLIC USE16
+section _DATA           align=2   CLASS=DATA     PUBLIC USE16
+ %ifdef BS3_IS_DOS_EXE
+section XIB             align=1   CLASS=DATA     PUBLIC USE16
+section XI              align=1   CLASS=DATA     PUBLIC USE16
+section XIE             align=1   CLASS=DATA     PUBLIC USE16
+section YIB             align=1   CLASS=DATA     PUBLIC USE16
+section YI              align=1   CLASS=DATA     PUBLIC USE16
+section YIE             align=1   CLASS=DATA     PUBLIC USE16
+ %endif
+section STRINGS         align=2   CLASS=DATA     PUBLIC USE16
+section DATA            align=2   CLASS=DATA     PUBLIC USE16
+section _BSS            align=2   CLASS=BS3KIT_CLASS_BSS16 PUBLIC USE16
+section BSS             align=2   CLASS=BS3KIT_CLASS_BSS16 PUBLIC USE16
+ %ifdef BS3_IS_DOS_EXE
+section STACK           align=16  CLASS=STACK    STACK  USE16
+ %endif
+section BS3DATA16_END   align=2   CLASS=BS3KIT_CLASS_BSS16 PUBLIC USE16
 %endif
 
@@ -95,5 +137,13 @@
 
 %ifndef ASM_FORMAT_ELF
-GROUP BS3DATA16_GROUP BS3DATA16 BS3DATA16_DATA BS3DATA16CONST BS3DATA16CONST2 BS3DATA16_END
+ %ifndef BS3_IS_DOS_EXE
+GROUP BS3KIT_GRPNM_DATA16 BS3DATA16 BS3DATA16_DATA _DATA DATA BS3DATA16CONST CONST BS3DATA16CONST2 CONST2 STRINGS _BSS BSS BS3DATA16_END
+ %else
+GROUP BS3KIT_GRPNM_DATA16 \
+    _NULL _AFTERNULL \
+    CONST BS3DATA16CONST CONST2 BS3DATA16CONST2 _DATA XIB XI XIE YIB YI YIE STRINGS DATA BS3DATA16 BS3DATA16_DATA \
+    _BSS BSS BS3DATA16_END \
+    STACK
+ %endif
 %endif
 
@@ -122,11 +172,4 @@
     db      10,13,'eye-catcher: BS3TEXT64',10,13
 
-%ifdef ASM_FORMAT_OMF
-;section TEXT64 align=4 CLASS=CODE PUBLIC USE32
-;section .text  align=4 CLASS=CODE PUBLIC USE32 - nasm doesn't do '.' at the start of segments in OMF mode. Not that this helps anyways...
-;section .rdata align=4 CLASS=CODE PUBLIC USE32
-;GROUP CODE64 TEXT64 _text _rdata
-%endif
-
 %ifdef ASM_FORMAT_ELF
 section BS3TEXT64_END   align=1 progbits alloc exec nowrite
@@ -136,4 +179,11 @@
 BS3_GLOBAL_DATA Bs3Text64_EndOfSegment, 0
 
+
+;
+; FAR_DATA segment in DOS EXEs should be near the other FAR_DATA class segments.
+;
+%ifdef BS3_IS_DOS_EXE
+section FAR_DATA        align=1 CLASS=FAR_DATA PUBLIC USE16
+%endif
 
 ;
@@ -149,4 +199,5 @@
 section BS3DATA32CONST2 align=16   CLASS=FAR_DATA PUBLIC USE32
 section BS3DATA32_DATA  align=16   CLASS=FAR_DATA PUBLIC USE32
+section BS3DATA32_BSS   align=16   CLASS=FAR_DATA PUBLIC USE32
 section BS3DATA32_END   align=16   CLASS=FAR_DATA PUBLIC USE32
 %endif
@@ -154,5 +205,5 @@
 
 %ifndef ASM_FORMAT_ELF
-GROUP BS3DATA32_GROUP BS3DATA32 BS3DATA32_DATA BS3DATA32CONST BS3DATA32CONST2 BS3DATA32_END
+GROUP BS3DATA32_GROUP BS3DATA32 BS3DATA32_DATA BS3DATA32CONST BS3DATA32CONST2 BS3DATA32_BSS BS3DATA32_END
 %endif
 
@@ -166,9 +217,6 @@
 section BS3DATA64_END   align=16   progbits alloc noexec write
 %else
-;section .data           align=8    CLASS=DATA PUBLIC USE32
-;section .rdata          align=8    CLASS=DATA PUBLIC USE32
-;section .xdata          align=8    CLASS=DATA PUBLIC USE32
-;section .pdata          align=8    CLASS=DATA PUBLIC USE32
-;section .bss            align=8    CLASS=DATA PUBLIC USE32
+section BS3DATA64CONST  align=16   CLASS=FAR_DATA PUBLIC USE32
+section BS3DATA64_BSS   align=16   CLASS=FAR_DATA PUBLIC USE32
 section BS3DATA64_END   align=16   CLASS=FAR_DATA PUBLIC USE32
 %endif
@@ -176,6 +224,5 @@
 
 %ifndef ASM_FORMAT_ELF
-;GROUP BS3DATA64_GROUP BS3DATA64 .data .rdata .xdata .pdata .bss BS3DATA64_END
-GROUP BS3DATA64_GROUP BS3DATA64 BS3DATA64_END
+GROUP BS3DATA64_GROUP BS3DATA64 BS3DATA64CONST BS3DATA64_BSS BS3DATA64_END
 %endif
 
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-first-dosexe.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-first-dosexe.asm	(revision 60439)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-first-dosexe.asm	(revision 60439)
@@ -0,0 +1,36 @@
+; $Id$
+;; @file
+; BS3Kit - First Object for DOS executables, defines segments only.
+;
+
+;
+; Copyright (C) 2007-2016 Oracle Corporation
+;
+; This file is part of VirtualBox Open Source Edition (OSE), as
+; available from http://www.virtualbox.org. This file is free software;
+; you can redistribute it and/or modify it under the terms of the GNU
+; General Public License (GPL) as published by the Free Software
+; Foundation, in version 2 as it comes in the "COPYING" file of the
+; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+;
+; The contents of this file may alternatively be used under the terms
+; of the Common Development and Distribution License Version 1.0
+; (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+; VirtualBox OSE distribution, in which case the provisions of the
+; CDDL are applicable instead of those of the GPL.
+;
+; You may elect to license modified versions of this file under the
+; terms and conditions of either the GPL or the CDDL or both.
+;
+
+
+%include "bs3kit.mac"
+
+;
+; Segment defs, grouping and related variables.
+; Defines the entry point 'start' as well, leaving us in BS3TEXT16.
+;
+%include "bs3-first-common.mac"
+
+
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-first-rm.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-first-rm.asm	(revision 60438)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-first-rm.asm	(revision 60439)
@@ -45,5 +45,5 @@
         ; Nothing to init here, just call main and shutdown if it returns.
         ;
-        mov     ax, BS3DATA16
+        mov     ax, BS3_SEL_DATA16
         mov     es, ax
         mov     ds, ax
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-SwitchToRM.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-SwitchToRM.asm	(revision 60438)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-SwitchToRM.asm	(revision 60439)
@@ -30,4 +30,18 @@
 %if TMPL_MODE == BS3_MODE_PE16
 BS3_EXTERN_DATA16 g_uBs3CpuDetected
+BS3_EXTERN_CMN Bs3KbdWrite
+BS3_EXTERN_CMN Bs3KbdWait
+%endif
+
+
+;*********************************************************************************************************************************
+;*  Global Variables                                                                                                             *
+;*********************************************************************************************************************************
+%if TMPL_MODE == BS3_MODE_PE16
+BS3_BEGIN_DATA16
+;; Where to start restoring stack.
+g_ResumeSp: dw 0xfeed
+;; Where to start restoring stack.
+g_ResumeSs: dw 0xface
 %endif
 
@@ -107,14 +121,116 @@
         ; On 80286 we must reset the CPU to get back to real mode.
         ;
+        CPU 286
         pop     ax
         push    ax
         test    ax, ax
         jz      .is_386_or_better
-.implement_this_later:
-        int3
-        jmp     .implement_this_later
-
-        jmp     .reload_cs
-
+
+        ; Save registers and flags, storing SS:SP in at a known global address.
+%ifdef BS3_STRICT
+        mov     ax, 0feedh
+        mov     bx, 0faceh
+%endif
+        push    di
+        push    si
+        push    bp
+        push    bx
+        push    dx
+        push    cx
+        push    ax
+        pushf
+
+        ; Convert ss:sp to real mode address.
+        BS3_EXTERN_CMN Bs3SelProtFar32ToFlat32
+        mov     ax, sp
+        push    ss
+        push    0
+        push    ax
+        call    Bs3SelProtFar32ToFlat32
+        add     sp, 6
+
+        mov     [g_ResumeSp], ax
+        shl     dx, 12
+        mov     [g_ResumeSs], dx
+
+        ; Setup resume vector.
+        mov     bx, BS3_SEL_R0_SS16
+        mov     es, bx
+        mov     word [es:467h],   .resume
+        mov     word [es:467h+2], BS3_SEL_TEXT16
+
+        mov     al, 0fh | 80h
+        out     70h, al                 ; set register index
+        in      al, 80h
+        mov     al, 0ah                 ; shutdown action command - no EOI, no 287 reset.
+        out     71h, al                 ; set cmos[f] = al - invoke testResume as early as possible.
+        in      al, 71h                 ; flush
+
+ %if 0 ; for testing in VM
+        CPU 386
+        mov     ax, BS3_SEL_R0_DS16
+        mov     ds, ax
+        mov     es, ax
+        mov     fs, ax
+        mov     gs, ax
+
+        mov     eax, cr0
+        and     ax, ~X86_CR0_PE
+        mov     cr0, eax
+hlt
+        jmp     BS3_SEL_TEXT16:.resume
+ %endif
+
+        ; Port A reset. (FYI: tripple fault does not do the trick)
+        in      al, 92h
+        or      al, 1
+        out     92h, al
+        in      al, 80h                 ; flush
+        mov     cx, 0ffffh
+.reset_delay:
+        loop    .reset_delay
+
+        ; Keyboard controller reset.
+        call    Bs3KbdWait
+        push    0                       ; zero data (whatever.
+        push    0fh                     ; KBD_CCMD_RESET
+        call    Bs3KbdWrite
+.forever:
+        jmp     .forever
+
+        ; This is the resume point. We should be in real mode now, at least in theory.
+.resume:
+        mov     ax, BS3_SEL_DATA16
+        mov     ds, ax
+        mov     es, ax
+        mov     ax, [g_ResumeSp]
+        mov     ss, [g_ResumeSs]
+        mov     sp, ax
+
+        popf
+        pop     ax
+        pop     cx
+        pop     dx
+        pop     bx
+        pop     bp
+        pop     si
+        pop     di
+ %ifdef BS3_STRICT
+        cmp     ax, 0feedh
+        jne     .bad_286_rm_switch
+        cmp     bx, 0faceh
+        jne     .bad_286_rm_switch
+ %endif
+        jmp     .enter_mode
+
+ %ifdef BS3_STRICT
+.bad_286_rm_switch:
+        mov ax, 0e00h + 'Q'
+        mov bx, 0ff00h
+        int 10h
+        jmp     .bad_286_rm_switch
+ %endif
+
+        CPU 386
  %elif TMPL_BITS != 16
         ;
@@ -163,10 +279,10 @@
         add     sp, [bx + 2 + Bs3Gdt]   ; ASSUMES not expand down segment.
         adc     ax, 0
-%ifdef BS3_STRICT
+ %ifdef BS3_STRICT
         test    ax, 0fff0h
         jz      .stack_conv_ok
         int3
 .stack_conv_ok:
-%endif
+ %endif
         shl     ax, 12
         mov     ss, ax
@@ -188,4 +304,5 @@
         ; Call routine for doing mode specific setups.
         ;
+.enter_mode:
         extern  NAME(Bs3EnteredMode_rm)
         call    NAME(Bs3EnteredMode_rm)
@@ -198,5 +315,5 @@
         pop     bx
         pop     ax
-        pop     bp
+        ret
  %endif
 .do_386_epilogue:
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-TestDoModesHlp.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-TestDoModesHlp.asm	(revision 60438)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-TestDoModesHlp.asm	(revision 60439)
@@ -158,7 +158,7 @@
 ;
 ; For checking that the mode switching macros doesn't screw up GPRs.
-; Note! Does not work on pre 286 hardware!
-;
-%ifdef BS3_STRICT
+; Note! Does not work on pre 286 hardware! So, for debugging only.
+;
+%if 0
  %macro STRICT_SAVE_REGS 0
         movzx   esp, sp
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-TrapSystemCallHandler.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-TrapSystemCallHandler.asm	(revision 60438)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-TrapSystemCallHandler.asm	(revision 60439)
@@ -103,10 +103,10 @@
         push    ds
  %ifdef TMPL_CMN_R86
-        push    BS3DATA16
+        push    BS3_SEL_DATA16
  %else
         push    RT_CONCAT(BS3_SEL_R0_DS,TMPL_BITS)
  %endif
-        pop     ds                      ; DS = BS3DATA16_GROUP or FLAT and we can safely access data
- %if TMPL_BITS == 16 && (TMPL_MODE == BS3_MODE_SYS_RM || TMPL_MODE == BS3_MODE_SYS_PE16)
+        pop     ds                      ; DS = BS3KIT_GRPNM_DATA16 or FLAT and we can safely access data
+ %if TMPL_BITS == 16 && (TMPL_MODE == BS3_MODE_RM || TMPL_MODE == BS3_MODE_PE16)
         cmp     byte [BS3_DATA16_WRT(g_uBs3CpuDetected)], BS3CPU_80286
         jbe     .prologue_pre_80386
@@ -123,5 +123,5 @@
         push    esp
         pushfd
- %if TMPL_MODE == BS3_MODE_SYS_RM || TMPL_MODE == BS3_MODE_SYS_PE16
+ %if TMPL_MODE == BS3_MODE_RM || TMPL_MODE == BS3_MODE_PE16
         jmp     .prologue_end
 
@@ -157,5 +157,5 @@
         cmp     ax, BS3_SYSCALL_LAST
         ja      .invalid_syscall
-%ifdef TMPL_16BIT
+%if TMPL_BITS == 16
         mov     bx, ax
         shl     bx, 1
@@ -362,5 +362,5 @@
         cmp     bl, BS3_MODE_CODE_32
         je      .return_to_32bit_from_16bit_krnl
- %if TMPL_MODE == BS3_MODE_SYS_RM || TMPL_MODE == BS3_MODE_SYS_PE16
+ %if TMPL_MODE == BS3_MODE_RM || TMPL_MODE == BS3_MODE_PE16
         cmp     byte [BS3_DATA16_WRT(g_uBs3CpuDetected)], BS3CPU_80286
         jbe     .return_pre_80386
@@ -389,19 +389,19 @@
 
 %if TMPL_BITS == 16
- %if TMPL_MODE == BS3_MODE_SYS_RM || TMPL_MODE == BS3_MODE_SYS_PE16
+ %if TMPL_MODE == BS3_MODE_RM || TMPL_MODE == BS3_MODE_PE16
         ; Variant of the above for 80286 and older.
 .return_pre_80386:
         add     sp, 0ch
         pop     di
-        pop     di
+        pop     bx                      ; dummy
         pop     si
-        pop     si
+        pop     bx                      ; dummy
         pop     dx
-        pop     dx
+        pop     bx                      ; dummy
         pop     cx
-        pop     cx
+        pop     bx                      ; dummy
         pop     ax
-        pop     ax
-        pop     bx
+        pop     bx                      ; dummy
+        pop     bx                      ; pushed twice
         pop     bx
         pop     ds
@@ -756,4 +756,7 @@
         ret
 
+%if TMPL_BITS == 16
+        CPU 286
+%endif
 
         ;
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-system-data.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-system-data.asm	(revision 60438)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-system-data.asm	(revision 60439)
@@ -422,5 +422,5 @@
 
         ;
-        ; 2900h - the real mode segment number for BS3DATA16. DPL=3. BASE=0x29000h
+        ; 2900h - the real mode segment number for BS3KIT_GRPNM_DATA16. DPL=3. BASE=0x29000h
         ;
 BS3GdtAssertOffset 02900h
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3cpudt.c
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3cpudt.c	(revision 60439)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3cpudt.c	(revision 60439)
@@ -0,0 +1,61 @@
+/* $Id$ */
+/** @file
+ * BS3Kit - Tests Bs3CpuDetect_rm.
+ */
+
+/*
+ * Copyright (C) 2007-2016 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+
+#include "bs3kit.h"
+#include <stdio.h>
+#include <stdint.h>
+
+
+unsigned StoreMsw(void);
+#pragma aux StoreMsw = \
+    ".286" \
+    "smsw ax" \
+    value [ax];
+
+void LoadMsw(unsigned);
+#pragma aux LoadMsw = \
+    ".286p" \
+    "lmsw ax" \
+    parm [ax];
+
+int main()
+{
+    uint16_t volatile usCpu = Bs3CpuDetect_rm();
+    printf("usCpu=%#x\n", usCpu);
+    if ((usCpu & BS3CPU_TYPE_MASK) >= BS3CPU_80286)
+    {
+        printf("(42=%d) msw=%#x (42=%d)\n", 42, StoreMsw(), 42);
+        LoadMsw(0);
+        printf("lmsw 0 => msw=%#x (42=%d)\n", StoreMsw(), 42);
+    }
+    return 0;
+}
+
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-template-header.mac
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-template-header.mac	(revision 60438)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-template-header.mac	(revision 60439)
@@ -403,5 +403,5 @@
 ;
 %ifdef TMPL_16BIT
- %define TMPL_WRT_DATA16_OR_FLAT    wrt BS3DATA16
+ %define TMPL_WRT_DATA16_OR_FLAT    wrt BS3KIT_GRPNM_DATA16
 %else
  %define TMPL_WRT_DATA16_OR_FLAT    wrt FLAT
@@ -413,5 +413,5 @@
 ;
 %if TMPL_BITS == 16
- %define TMPL_DATA16_WRT(a_Var)     a_Var wrt BS3DATA16
+ %define TMPL_DATA16_WRT(a_Var)     a_Var wrt BS3KIT_GRPNM_DATA16
 %elif TMPL_BITS == 32
  %define TMPL_DATA16_WRT(a_Var)     a_Var wrt FLAT
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h	(revision 60438)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h	(revision 60439)
@@ -182,5 +182,5 @@
  * @sa BS3_SEL_SYSTEM16 */
 #define BS3_ADDR_BS3SYSTEM16    0x20000
-/** The base address of the BS3DATA16 segment.
+/** The base address of the BS3DATA16/BS3KIT_GRPNM_DATA16 segment.
  * @sa BS3_SEL_DATA16 */
 #define BS3_ADDR_BS3DATA16      0x29000
@@ -354,5 +354,5 @@
 #define BS3_SEL_FREE_PART3_LAST     0x28f8 /**< Free selector space - part \#3, last entry. */
 
-#define BS3_SEL_DATA16              0x2900 /**< The BS3DATA16 selector. */
+#define BS3_SEL_DATA16              0x2900 /**< The BS3DATA16/BS3KIT_GRPNM_DATA16 selector. */
 
 #define BS3_SEL_FREE_PART4          0x2908 /**< Free selector space - part \#4. */
@@ -945,5 +945,5 @@
 /** Free GDTes, part \#3. */
 extern X86DESC BS3_FAR_DATA Bs3GdteFreePart3[223];
-/** The BS3DATA16/BS3_FAR_DATA GDT entry. */
+/** The BS3DATA16/BS3KIT_GRPNM_DATA16 GDT entry. */
 extern X86DESC BS3_FAR_DATA Bs3Gdte_DATA16;
 /** Free GDTes, part \#4. */
@@ -1050,10 +1050,10 @@
 extern uint8_t  BS3_FAR_DATA Bs3System16_EndOfSegment;
 
-/** Start of the BS3DATA16 segment.   */
+/** Start of the BS3DATA16/BS3KIT_GRPNM_DATA16 segment.   */
 #ifndef DOXYGEN_RUNNING
 # define Bs3Data16_StartOfSegment BS3_DATA_NM(Bs3Data16_StartOfSegment)
 #endif
 extern uint8_t  BS3_FAR_DATA Bs3Data16_StartOfSegment;
-/** End of the BS3DATA16 segment.   */
+/** End of the BS3DATA16/BS3KIT_GRPNM_DATA16 segment.   */
 #ifndef DOXYGEN_RUNNING
 # define Bs3Data16_EndOfSegment BS3_DATA_NM(Bs3Data16_EndOfSegment)
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.mac
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.mac	(revision 60438)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.mac	(revision 60439)
@@ -213,5 +213,5 @@
  %undef BS3_DATA16_WRT
  %if %1 == 16
-  %define BS3_DATA16_WRT(a_Var)     a_Var wrt BS3DATA16
+  %define BS3_DATA16_WRT(a_Var)     a_Var wrt BS3KIT_GRPNM_DATA16
  %elif %1 == 32
   %define BS3_DATA16_WRT(a_Var)     a_Var wrt FLAT
@@ -346,4 +346,5 @@
 %endif
 
+
 %macro BS3_BEGIN_TEXT16 0
  %ifndef  BS3_BEGIN_TEXT16_NOT_FIRST
@@ -366,5 +367,8 @@
         section BS3DATA16 align=2 progbits alloc noexec write
   %else
-        section BS3DATA16 align=2 CLASS=FAR_DATA PUBLIC USE16
+        section BS3DATA16 align=2 CLASS=BS3KIT_CLASS_DATA16 PUBLIC USE16
+   %ifndef BS3_BEGIN_DATA16_WITHOUT_GROUP ; bs3-first-common.mac trick.
+    GROUP BS3KIT_GRPNM_DATA16 BS3DATA16
+   %endif
   %endif
  %else
@@ -1119,5 +1123,5 @@
 ;; @sa BS3_SEL_SYSTEM16
 %define BS3_ADDR_BS3SYSTEM16    020000h
-;; The base address of the BS3DATA16 segment.
+;; The base address of the BS3DATA16/BS3KIT_GRPNM_DATA16 segment.
 ;; @sa BS3_SEL_DATA16
 %define BS3_ADDR_BS3DATA16      029000h
@@ -1396,5 +1400,5 @@
 %define BS3_SEL_FREE_PART3_LAST     28f8h ;;< Free selector space - part \%3, last entry.
 
-%define BS3_SEL_DATA16              2900h ;;< The BS3DATA16 selector.
+%define BS3_SEL_DATA16              2900h ;;< The BS3DATA16/BS3KIT_GRPNM_DATA16 selector.
 
 %define BS3_SEL_FREE_PART4          2908h ;;< Free selector space - part \#4.
