- Added in some code from XFree86 to save the vga state on the startup
authorDavid Welch <welch@cwcom.net>
Sun, 24 Aug 2003 20:56:16 +0000 (20:56 +0000)
committerDavid Welch <welch@cwcom.net>
Sun, 24 Aug 2003 20:56:16 +0000 (20:56 +0000)
and restore it on a bugcheck.

svn path=/trunk/; revision=5836

reactos/CREDITS
reactos/hal/halx86/display.c

index 9184dbb..9e40277 100644 (file)
@@ -19,6 +19,7 @@ Source and inspiration from
 WINE (http://www.winehq.com)
 WinFree (http://www.stack.nl/~onno/win32/)
 Linux (http://www.kernel.org)
 WINE (http://www.winehq.com)
 WinFree (http://www.stack.nl/~onno/win32/)
 Linux (http://www.kernel.org)
+XFree86 (http://www.xfree86.org/)
 
 References (Rex's at least)
 
 
 References (Rex's at least)
 
index 40c03d5..f5eee9b 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: display.c,v 1.7 2003/08/24 11:58:16 dwelch Exp $
+/* $Id: display.c,v 1.8 2003/08/24 20:56:16 dwelch Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  *                  Created 08/10/99
  */
 
  *                  Created 08/10/99
  */
 
+/*
+ * Portions of this code are from the XFree86 Project and available from the
+ * following license:
+ *
+ * Copyright (C) 1994-2003 The XFree86 Project, Inc.  All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
+ * NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the XFree86 Project shall
+ * not be used in advertising or otherwise to promote the sale, use or other
+ * dealings in this Software without prior written authorization from the
+ * XFree86 Project.
+*/  
+
 /* DISPLAY OWNERSHIP
  *
  * So, who owns the physical display and is allowed to write to it?
 /* DISPLAY OWNERSHIP
  *
  * So, who owns the physical display and is allowed to write to it?
 #define SCREEN_SYNCHRONIZATION
 
 #define VGA_AC_INDEX            0x3c0
 #define SCREEN_SYNCHRONIZATION
 
 #define VGA_AC_INDEX            0x3c0
-#define VGA_AC_READ             0x3c0
-#define VGA_AC_WRITE            0x3c1
+#define VGA_AC_READ             0x3c1
+#define VGA_AC_WRITE            0x3c0
 
 #define VGA_MISC_WRITE          0x3c2
 
 #define VGA_SEQ_INDEX           0x3c4
 #define VGA_SEQ_DATA            0x3c5
 
 
 #define VGA_MISC_WRITE          0x3c2
 
 #define VGA_SEQ_INDEX           0x3c4
 #define VGA_SEQ_DATA            0x3c5
 
+#define VGA_DAC_MASK            0x3c8
 #define VGA_DAC_READ_INDEX      0x3c7
 #define VGA_DAC_WRITE_INDEX     0x3c8
 #define VGA_DAC_DATA            0x3c9
 #define VGA_DAC_READ_INDEX      0x3c7
 #define VGA_DAC_WRITE_INDEX     0x3c8
 #define VGA_DAC_DATA            0x3c9
-
+#define VGA_FEATURE_READ        0x3ca
 #define VGA_MISC_READ           0x3cc
 
 #define VGA_GC_INDEX            0x3ce
 #define VGA_MISC_READ           0x3cc
 
 #define VGA_GC_INDEX            0x3ce
 #define CHAR_ATTRIBUTE_BLACK  0x00  /* black on black */
 #define CHAR_ATTRIBUTE        0x17  /* grey on blue */
 
 #define CHAR_ATTRIBUTE_BLACK  0x00  /* black on black */
 #define CHAR_ATTRIBUTE        0x17  /* grey on blue */
 
+#define FONT_AMOUNT        (8*8192)
 
 /* VARIABLES ****************************************************************/
 
 
 /* VARIABLES ****************************************************************/
 
@@ -149,117 +180,18 @@ static BOOLEAN DisplayInitialized = FALSE;
 static BOOLEAN HalOwnsDisplay = TRUE;
 
 static WORD *VideoBuffer = NULL;
 static BOOLEAN HalOwnsDisplay = TRUE;
 
 static WORD *VideoBuffer = NULL;
+static PUCHAR GraphVideoBuffer = NULL;
 
 static PHAL_RESET_DISPLAY_PARAMETERS HalResetDisplayParameters = NULL;
 
 
 static PHAL_RESET_DISPLAY_PARAMETERS HalResetDisplayParameters = NULL;
 
-static UCHAR TextPalette[64][3] = 
-  {
-    {0, 0, 0}    /* 0 */,
-    {0, 0, 42}   /* 1 */,
-    {0, 42, 0}   /* 2 */,
-    {0, 42, 42}  /* 3 */,
-    {42, 0, 0}   /* 4 */,
-    {42, 42, 42} /* 5 */,
-    {42, 42, 0}  /* 6 */,
-    {42, 42, 42} /* 7 */,
-    {0, 0, 21}   /* 8 */,
-    {0, 0, 63}   /* 9 */,
-    {0, 42, 21}  /* 10 */,
-    {0, 42, 63}  /* 11 */,
-    {42, 0, 21}  /* 12 */,
-    {42, 0, 63}  /* 13 */,
-    {42, 42, 21} /* 14 */,
-    {42, 42, 63} /* 15 */,
-    {0, 21, 0}   /* 16 */,
-    {0, 21, 42}  /* 17 */,
-    {0, 63, 0}   /* 18 */,
-    {0, 63, 42}  /* 19 */,
-    {42, 21, 0}  /* 20 */,
-    {42, 21, 42} /* 21 */,
-    {42, 63, 0}   /* 22 */,
-    {42, 63, 42} /* 23 */,
-    {0, 21, 21}  /* 24 */,
-    {0, 21, 63}  /* 25 */,
-    {0, 63, 21}  /* 26 */,
-    {0, 63, 63}  /* 27 */,
-    {42, 21, 21} /* 28 */,
-    {42, 21, 63} /* 29 */,
-    {42, 63, 21} /* 30 */,
-    {42, 63, 63} /* 31 */,
-    {21, 0, 0}   /* 32 */,
-    {21, 0, 42}  /* 33 */,
-    {21, 42, 0}  /* 34 */,
-    {21, 42, 42} /* 35 */,
-    {63, 0, 0}   /* 36 */,
-    {63, 0, 42}  /* 37 */,
-    {63, 42, 0}  /* 38 */,
-    {63, 42, 42} /* 39 */,
-    {21, 0, 21}  /* 40 */,
-    {21, 0, 63}  /* 41 */,
-    {21, 42, 21} /* 42 */,
-    {21, 42, 63} /* 43 */,
-    {63, 42, 0}  /* 44 */,
-    {63, 0, 63}  /* 45 */,
-    {63, 42, 21} /* 46 */,
-    {63, 42, 63} /* 47 */,
-    {21, 21, 0}  /* 48 */,
-    {21, 21, 42} /* 49 */,
-    {21, 63, 0}  /* 50 */,
-    {21, 63, 42} /* 51 */,
-    {63, 21, 0}  /* 52 */,
-    {63, 21, 42} /* 53 */,
-    {63, 63, 0}  /* 54 */,
-    {63, 63, 42} /* 55 */,
-    {21, 21, 21} /* 56 */,
-    {21, 21, 63} /* 57 */,
-    {21, 63, 21} /* 58 */,
-    {21, 63, 63} /* 59 */,
-    {63, 21, 21} /* 60 */,
-    {63, 21, 63} /* 61 */,
-    {63, 63, 21} /* 62 */,
-    {63, 63, 63} /* 63 */,
-  };
-
-static UCHAR Text80x25Registers[] =
-{
-  /* MISC */
-  0x67,
-  /* SEQ */
-  0x03, 0x00, 0x03, 0x00, 0x02,
-  /* CRTC */
-  0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81, 0xBF, 0x1F,
-  0x00, 0x4F, 0x0D, 0x0E, 0x00, 0x00, 0x00, 0x50,
-  0x9C, 0x0E, 0x8F, 0x28, 0x1F, 0x96, 0xB9, 0xA3,
-  0xFF,
-  /* GC */
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x00,
-  0xFF,
-  /* AC */
-  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-  0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
-  0x0C, 0x00, 0x0F, 0x08, 0x00
-};
-
-static UCHAR Text80x50Registers[] =
-{
-  /* MISC */
-  0x67,
-  /* SEQ */
-  0x03, 0x00, 0x03, 0x00, 0x02,
-  /* CRTC */
-  0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81, 0xBF, 0x1F,
-  0x00, 0x47, 0x06, 0x07, 0x00, 0x00, 0x01, 0x40,
-  0x9C, 0x8E, 0x8F, 0x28, 0x1F, 0x96, 0xB9, 0xA3,
-  0xFF, 
-  /* GC */
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x00,
-  0xFF, 
-  /* AC */
-  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-  0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
-  0x0C, 0x00, 0x0F, 0x08, 0x00,
-};
-
+static UCHAR SavedTextPalette[768];
+static UCHAR SavedTextMiscOutReg;
+static UCHAR SavedTextCrtcReg[VGA_CRTC_NUM_REGISTERS];
+static UCHAR SavedTextAcReg[VGA_AC_NUM_REGISTERS];
+static UCHAR SavedTextGcReg[VGA_GC_NUM_REGISTERS];
+static UCHAR SavedTextSeqReg[VGA_SEQ_NUM_REGISTERS];
+static UCHAR SavedTextFont[2][FONT_AMOUNT];
+static BOOL TextPaletteEnabled = FALSE;
 
 /* STATIC FUNCTIONS *********************************************************/
 
 
 /* STATIC FUNCTIONS *********************************************************/
 
@@ -306,64 +238,327 @@ HalPutCharacter (CHAR Character)
 }
 
 VOID STATIC
 }
 
 VOID STATIC
-HalSetDisplayMode(PUCHAR Registers)
+HalDisablePalette(VOID)
+{
+  (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
+  WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, 0x20);
+  TextPaletteEnabled = FALSE;
+}
+
+VOID STATIC
+HalEnablePalette(VOID)
+{
+  (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
+  WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, 0x00);
+  TextPaletteEnabled = TRUE;
+}
+
+UCHAR STATIC
+HalReadGc(ULONG Index)
+{
+  WRITE_PORT_UCHAR((PUCHAR)VGA_GC_INDEX, Index);
+  return(READ_PORT_UCHAR((PUCHAR)VGA_GC_DATA));
+}
+
+VOID STATIC
+HalWriteGc(ULONG Index, UCHAR Value)
+{
+  WRITE_PORT_UCHAR((PUCHAR)VGA_GC_INDEX, Index);
+  WRITE_PORT_UCHAR((PUCHAR)VGA_GC_DATA, Value);
+}
+
+UCHAR STATIC
+HalReadSeq(ULONG Index)
+{
+  WRITE_PORT_UCHAR((PUCHAR)VGA_SEQ_INDEX, Index);
+  return(READ_PORT_UCHAR((PUCHAR)VGA_SEQ_DATA));
+}
+
+VOID STATIC
+HalWriteSeq(ULONG Index, UCHAR Value)
+{
+  WRITE_PORT_UCHAR((PUCHAR)VGA_SEQ_INDEX, Index);
+  WRITE_PORT_UCHAR((PUCHAR)VGA_SEQ_DATA, Value);
+}
+
+VOID STATIC
+HalWriteAc(ULONG Index, UCHAR Value)
 {
 {
-  UCHAR Port;
+  if (TextPaletteEnabled)
+    {
+      Index &= ~0x20;
+    }
+  else
+    {
+      Index |= 0x20;
+    }
+  (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
+  WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, Index);
+  WRITE_PORT_UCHAR((PUCHAR)VGA_AC_WRITE, Value);
+}
+
+UCHAR STATIC
+HalReadAc(ULONG Index)
+{
+  if (TextPaletteEnabled)
+    {
+      Index &= ~0x20;
+    }
+  else
+    {
+      Index |= 0x20;
+    }
+  (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
+  WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, Index);
+  return(READ_PORT_UCHAR((PUCHAR)VGA_AC_READ));
+}
+
+VOID STATIC
+HalWriteCrtc(ULONG Index, UCHAR Value)
+{
+  WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, Index);
+  WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA, Value);
+}
+
+UCHAR STATIC
+HalReadCrtc(ULONG Index)
+{
+  WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, Index);
+  return(READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA));
+}
+
+VOID STATIC
+HalResetSeq(BOOL Start)
+{
+  if (Start)
+    {
+      HalWriteSeq(0x00, 0x01);
+    }
+  else
+    {
+      HalWriteSeq(0x00, 0x03);
+    }
+}
+
+VOID STATIC
+HalBlankScreen(BOOL On)
+{
+  UCHAR Scrn;
+
+  Scrn = HalReadSeq(0x01);
+
+  if (On)
+    {
+      Scrn &= ~0x20;
+    }
+  else
+    {
+      Scrn |= 0x20;
+    }
+
+  HalResetSeq(TRUE);
+  HalWriteSeq(0x01, Scrn);
+  HalResetSeq(FALSE);
+}
+
+VOID STATIC
+HalSaveFont(VOID)
+{
+  UCHAR Attr10;
+  UCHAR MiscOut, Gc4, Gc5, Gc6, Seq2, Seq4;
   ULONG i;
 
   ULONG i;
 
-  /* Write MISC register. */
-  WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, *Registers);
-  Registers++;
-  /* Write SEQUENCER registers. */
+  /* Check if we are already in graphics mode. */
+  Attr10 = HalReadAc(0x10);
+  if (Attr10 & 0x01)
+    {
+      return;
+    }
+
+  /* Save registers. */
+  MiscOut = READ_PORT_UCHAR((PUCHAR)VGA_MISC_READ);
+  Gc4 = HalReadGc(0x04);
+  Gc5 = HalReadGc(0x05);
+  Gc6 = HalReadGc(0x06);
+  Seq2 = HalReadSeq(0x02);
+  Seq4 = HalReadSeq(0x04);
+
+  /* Force colour mode. */
+  WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, MiscOut | 0x01);
+
+  HalBlankScreen(FALSE);
+
+  for (i = 0; i < 2; i++)
+    {
+      /* Save font 1 */
+      HalWriteSeq(0x02, 0x04 << i); /* Write to plane 2 or 3 */
+      HalWriteSeq(0x04, 0x06); /* Enable plane graphics. */
+      HalWriteGc(0x04, 0x02 + i); /* Read plane 2 or 3 */
+      HalWriteGc(0x05, 0x00); /* Write mode 0; read mode 0 */
+      HalWriteGc(0x06, 0x05); /* Set graphics. */
+      memcpy(SavedTextFont[i], GraphVideoBuffer, FONT_AMOUNT);
+    }
+
+  /* Restore registers. */
+  HalWriteAc(0x10, Attr10);
+  HalWriteSeq(0x02, Seq2);
+  HalWriteSeq(0x04, Seq4);
+  HalWriteGc(0x04, Gc4);
+  HalWriteGc(0x05, Gc5);
+  HalWriteGc(0x06, Gc6);
+  WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, MiscOut);
+
+  HalBlankScreen(TRUE);
+}
+
+VOID STATIC
+HalSaveMode(VOID)
+{
+  ULONG i;
+
+  SavedTextMiscOutReg = READ_PORT_UCHAR((PUCHAR)VGA_MISC_READ);
+
+  for (i = 0; i < VGA_CRTC_NUM_REGISTERS; i++)
+    {
+      SavedTextCrtcReg[i] = HalReadCrtc(i);
+    }
+
+  HalEnablePalette();
+  for (i = 0; i < VGA_AC_NUM_REGISTERS; i++)
+    {
+      SavedTextAcReg[i] = HalReadAc(i);
+    }
+  HalDisablePalette();
+
+  for (i = 0; i < VGA_GC_NUM_REGISTERS; i++)
+    {
+      SavedTextGcReg[i] = HalReadGc(i);
+    }
+
   for (i = 0; i < VGA_SEQ_NUM_REGISTERS; i++)
     {
   for (i = 0; i < VGA_SEQ_NUM_REGISTERS; i++)
     {
-      WRITE_PORT_UCHAR((PUCHAR)VGA_SEQ_INDEX, i);
-      WRITE_PORT_UCHAR((PUCHAR)VGA_SEQ_DATA, *Registers);
-      Registers++;
+      SavedTextSeqReg[i] = HalReadSeq(i);
+    }
+}
+
+VOID STATIC
+HalDacDelay(VOID)
+{
+  (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
+  (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
+}
+
+VOID STATIC
+HalSavePalette(VOID)
+{
+  ULONG i;
+  WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_MASK, 0xFF);
+  WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_READ_INDEX, 0x00);
+  for (i = 0; i < 768; i++)
+    {
+      SavedTextPalette[i] = READ_PORT_UCHAR((PUCHAR)VGA_DAC_DATA);
+      HalDacDelay();
+    }
+}
+
+VOID STATIC
+HalRestoreFont(VOID)
+{
+  UCHAR MiscOut, Attr10, Gc1, Gc3, Gc4, Gc5, Gc6, Gc8;
+  UCHAR Seq2, Seq4;
+  ULONG i;
+
+  /* Save registers. */
+  MiscOut = READ_PORT_UCHAR((PUCHAR)VGA_MISC_READ);
+  Attr10 = HalReadAc(0x10);
+  Gc1 = HalReadGc(0x01);
+  Gc3 = HalReadGc(0x03);
+  Gc4 = HalReadGc(0x04);
+  Gc5 = HalReadGc(0x05);
+  Gc6 = HalReadGc(0x06);
+  Gc8 = HalReadGc(0x08);
+  Seq2 = HalReadSeq(0x02);
+  Seq4 = HalReadSeq(0x04);
+
+  /* Force into colour mode. */
+  WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, MiscOut | 0x10);
+
+  HalBlankScreen(FALSE);
+
+  HalWriteGc(0x03, 0x00);  /* Don't rotate; write unmodified. */
+  HalWriteGc(0x08, 0xFF);  /* Write all bits. */
+  HalWriteGc(0x01, 0x00);  /* All planes from CPU. */
+
+  for (i = 0; i < 2; i++)
+    {
+      HalWriteSeq(0x02, 0x04 << i); /* Write to plane 2 or 3 */
+      HalWriteSeq(0x04, 0x06); /* Enable plane graphics. */
+      HalWriteGc(0x04, 0x02 + i); /* Read plane 2 or 3 */
+      HalWriteGc(0x05, 0x00); /* Write mode 0; read mode 0. */
+      HalWriteGc(0x06, 0x05); /* Set graphics. */
+      memcpy(GraphVideoBuffer, SavedTextFont[i], FONT_AMOUNT);
     }
     }
-  /* Unlock CRTC registers. */
-  WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, 0x03);
-  Port = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA);
-  WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA, Port | 0x80);
-  WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, 0x11);
-  Port = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA);
-  WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA, Port & ~0x80);
-  /* Make sure they stay unlocked. */
-  Registers[0x03] |= 0x80;
-  Registers[0x11] &= ~0x80;
-  /* Write CRTC registers. */
+
+  HalBlankScreen(TRUE);
+
+  /* Restore registers. */
+  WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, MiscOut);
+  HalWriteAc(0x10, Attr10);
+  HalWriteGc(0x01, Gc1);
+  HalWriteGc(0x03, Gc3);
+  HalWriteGc(0x04, Gc4);
+  HalWriteGc(0x05, Gc5);
+  HalWriteGc(0x06, Gc6);
+  HalWriteGc(0x08, Gc8);
+  HalWriteSeq(0x02, Seq2);
+  HalWriteSeq(0x04, Seq4);
+}
+
+VOID STATIC
+HalRestoreMode(VOID)
+{
+  ULONG i;
+
+  WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, SavedTextMiscOutReg);
+
+  for (i = 1; i < VGA_SEQ_NUM_REGISTERS; i++)
+    {
+      HalWriteSeq(i, SavedTextSeqReg[i]);
+    }
+
+  /* Unlock CRTC registers 0-7 */
+  HalWriteCrtc(17, SavedTextCrtcReg[17] & ~0x80);
+
   for (i = 0; i < VGA_CRTC_NUM_REGISTERS; i++)
     {
   for (i = 0; i < VGA_CRTC_NUM_REGISTERS; i++)
     {
-      WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, i);
-      WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA, *Registers);
-      Registers++;
+      HalWriteCrtc(i, SavedTextCrtcReg[i]);
     }
     }
-  /* Write GC registers. */
+
   for (i = 0; i < VGA_GC_NUM_REGISTERS; i++)
     {
   for (i = 0; i < VGA_GC_NUM_REGISTERS; i++)
     {
-      WRITE_PORT_UCHAR((PUCHAR)VGA_GC_INDEX, i);
-      WRITE_PORT_UCHAR((PUCHAR)VGA_GC_DATA, *Registers);
-      Registers++;
+      HalWriteGc(i, SavedTextGcReg[i]);
     }
     }
-  /* Write AC registers. */
+
+  HalEnablePalette();
   for (i = 0; i < VGA_AC_NUM_REGISTERS; i++)
     {
   for (i = 0; i < VGA_AC_NUM_REGISTERS; i++)
     {
-      (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
-      WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, i);
-      WRITE_PORT_UCHAR((PUCHAR)VGA_AC_WRITE, *Registers);
-      Registers++;
+      HalWriteAc(i, SavedTextAcReg[i]);
     }
     }
-  /* Reset palette. */
-  for (i = 0; i < 64; i++)
+  HalDisablePalette();
+}
+
+VOID STATIC
+HalRestorePalette(VOID)
+{
+  ULONG i;
+  WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_MASK, 0xFF);
+  WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_WRITE_INDEX, 0x00);
+  for (i = 0; i < 768; i++)
     {
     {
-      WRITE_PORT_UCHAR((PUCHAR)0x03c8, i);
-      WRITE_PORT_UCHAR((PUCHAR)0x03c9, TextPalette[i][0]);
-      WRITE_PORT_UCHAR((PUCHAR)0x03c9, TextPalette[i][1]);
-      WRITE_PORT_UCHAR((PUCHAR)0x03c9, TextPalette[i][2]);
+      WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_DATA, SavedTextPalette[i]);
+      HalDacDelay();
     }
     }
-  /* Lock 16-colour palette and unblank display. */
-  (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
-  WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, 0x20);  
+  HalDisablePalette();
 }
 
 /* PRIVATE FUNCTIONS ********************************************************/
 }
 
 /* PRIVATE FUNCTIONS ********************************************************/
@@ -382,6 +577,7 @@ HalInitializeDisplay (PLOADER_PARAMETER_BLOCK LoaderBlock)
       ULONG Data;
 
       VideoBuffer = (WORD *)(0xd0000000 + 0xb8000);
       ULONG Data;
 
       VideoBuffer = (WORD *)(0xd0000000 + 0xb8000);
+      GraphVideoBuffer = (PUCHAR)(0xd0000000 + 0xa0000);
 //      VideoBuffer = HalMapPhysicalMemory (0xb8000, 2);
 
       /* Set cursor position */
 //      VideoBuffer = HalMapPhysicalMemory (0xb8000, 2);
 
       /* Set cursor position */
@@ -410,6 +606,13 @@ HalInitializeDisplay (PLOADER_PARAMETER_BLOCK LoaderBlock)
       HalClearDisplay(CHAR_ATTRIBUTE_BLACK);
 
       DisplayInitialized = TRUE;
       HalClearDisplay(CHAR_ATTRIBUTE_BLACK);
 
       DisplayInitialized = TRUE;
+
+      /* 
+        Save the VGA state at this point so we can restore it on a bugcheck.
+      */
+      HalSavePalette();
+      HalSaveMode();
+      HalSaveFont();
     }
 }
 
     }
 }
 
@@ -430,16 +633,9 @@ HalReleaseDisplayOwnership()
 
   if (!HalResetDisplayParameters(SizeX, SizeY))
     {
 
   if (!HalResetDisplayParameters(SizeX, SizeY))
     {
-      if (SizeX == 80 && SizeY == 25)
-       {
-         HalSetDisplayMode(Text80x25Registers);
-       }
-      else
-       {
-         SizeX = 80;
-         SizeY = 50;
-         HalSetDisplayMode(Text80x50Registers);
-       }      
+      HalRestoreMode();
+      HalRestoreFont();
+      HalRestorePalette();
     }
   HalOwnsDisplay = TRUE;
   HalClearDisplay(CHAR_ATTRIBUTE);
     }
   HalOwnsDisplay = TRUE;
   HalClearDisplay(CHAR_ATTRIBUTE);