[FREELDR] Simplify the PrintText() and FrLdrBugCheckWithMessage() routines by using...
[reactos.git] / boot / freeldr / freeldr / arch / i386 / i386bug.c
index 1722b6c..f946396 100644 (file)
@@ -1,7 +1,6 @@
 
 #include <freeldr.h>
 
-#define NDEBUG
 #include <debug.h>
 
 typedef struct _FRAME
@@ -10,7 +9,7 @@ typedef struct _FRAME
     void *Address;
 } FRAME;
 
-char *i386ExceptionDescriptionText[] =
+static const CHAR *i386ExceptionDescriptionText[] =
 {
     "Exception 00: DIVIDE BY ZERO\n\n",
     "Exception 01: DEBUG EXCEPTION\n\n",
@@ -33,52 +32,68 @@ char *i386ExceptionDescriptionText[] =
     "Exception 12: MACHINE CHECK\n\n"
 };
 
-#define SCREEN_ATTR 0x1f
-void
-i386PrintChar(char chr, ULONG x, ULONG y)
+#define SCREEN_ATTR 0x1F    // Bright white on blue background
+
+/* Used to store the current X and Y position on the screen */
+static ULONG i386_ScreenPosX = 0;
+static ULONG i386_ScreenPosY = 0;
+
+#if 0
+static void
+i386PrintChar(CHAR chr, ULONG x, ULONG y)
 {
     MachVideoPutChar(chr, SCREEN_ATTR, x, y);
 }
+#endif
 
-/* Used to store the current X and Y position on the screen */
-ULONG i386_ScreenPosX = 0;
-ULONG i386_ScreenPosY = 0;
-
-void
-i386PrintText(char *pszText)
+static void
+i386PrintText(CHAR *pszText)
 {
-    char chr;
-    while (1)
-    {
-        chr = *pszText++;
+    ULONG Width, Unused;
 
-        if (chr == 0) break;
-        if (chr == '\n')
+    MachVideoGetDisplaySize(&Width, &Unused, &Unused);
+
+    for (; *pszText != ANSI_NULL; ++pszText)
+    {
+        if (*pszText == '\n')
         {
-            i386_ScreenPosY++;
             i386_ScreenPosX = 0;
+            ++i386_ScreenPosY;
             continue;
         }
 
-        MachVideoPutChar(chr, SCREEN_ATTR, i386_ScreenPosX, i386_ScreenPosY);
-        i386_ScreenPosX++;
+        MachVideoPutChar(*pszText, SCREEN_ATTR, i386_ScreenPosX, i386_ScreenPosY);
+        if (++i386_ScreenPosX >= Width)
+        {
+            i386_ScreenPosX = 0;
+            ++i386_ScreenPosY;
+        }
+    // FIXME: Implement vertical screen scrolling if we are at the end of the screen.
     }
 }
 
-void
-PrintText(const char *format, ...)
+static void
+PrintTextV(const CHAR *Format, va_list args)
+{
+    CHAR Buffer[512];
+
+    _vsnprintf(Buffer, sizeof(Buffer), Format, args);
+    Buffer[sizeof(Buffer) - 1] = ANSI_NULL;
+
+    i386PrintText(Buffer);
+}
+
+static void
+PrintText(const CHAR *Format, ...)
 {
     va_list argptr;
-    char buffer[256];
 
-    va_start(argptr, format);
-    _vsnprintf(buffer, sizeof(buffer), format, argptr);
-    buffer[sizeof(buffer) - 1] = 0;
+    va_start(argptr, Format);
+    PrintTextV(Format, argptr);
     va_end(argptr);
-    i386PrintText(buffer);
 }
 
-void
+static void
 i386PrintFrames(PKTRAP_FRAME TrapFrame)
 {
     FRAME *Frame;
@@ -86,11 +101,11 @@ i386PrintFrames(PKTRAP_FRAME TrapFrame)
     PrintText("Frames:\n");
 #ifdef _M_IX86
     for (Frame = (FRAME*)TrapFrame->Ebp;
-         Frame != 0 && (ULONG_PTR)Frame < STACK32ADDR;
+         Frame != 0 && (ULONG_PTR)Frame < STACKADDR;
          Frame = Frame->Next)
 #else
     for (Frame = (FRAME*)TrapFrame->TrapFrame;
-         Frame != 0 && (ULONG_PTR)Frame < STACK32ADDR;
+         Frame != 0 && (ULONG_PTR)Frame < STACKADDR;
          Frame = Frame->Next)
 #endif
     {
@@ -104,13 +119,13 @@ i386PrintExceptionText(ULONG TrapIndex, PKTRAP_FRAME TrapFrame, PKSPECIAL_REGIST
 {
     PUCHAR InstructionPointer;
 
+    MachVideoHideShowTextCursor(FALSE);
     MachVideoClearScreen(SCREEN_ATTR);
     i386_ScreenPosX = 0;
     i386_ScreenPosY = 0;
 
-    PrintText("An error occured in FreeLoader\n"
-              VERSION"\n"
-              "Report this error to the ReactOS Development mailing list <ros-dev@reactos.org>\n\n"
+    PrintText("An error occured in " VERSION "\n"
+              "Report this error on the ReactOS Bug Tracker: https://jira.reactos.org\n\n"
               "0x%02lx: %s\n", TrapIndex, i386ExceptionDescriptionText[TrapIndex]);
 #ifdef _M_IX86
     PrintText("EAX: %.8lx        ESP: %.8lx        CR0: %.8lx        DR0: %.8lx\n",
@@ -164,13 +179,46 @@ i386PrintExceptionText(ULONG TrapIndex, PKTRAP_FRAME TrapFrame, PKSPECIAL_REGIST
               TrapFrame->SegSs, Special->Ldtr, Special->Idtr.Limit);
     InstructionPointer = (PUCHAR)TrapFrame->Rip;
 #endif
-    PrintText("\nInstructionstream: %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x \n",
+    PrintText("\nInstruction stream: %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x \n",
               InstructionPointer[0], InstructionPointer[1],
               InstructionPointer[2], InstructionPointer[3],
               InstructionPointer[4], InstructionPointer[5],
               InstructionPointer[6], InstructionPointer[7]);
 }
 
+VOID
+FrLdrBugCheckWithMessage(
+    ULONG BugCode,
+    PCHAR File,
+    ULONG Line,
+    PSTR Format,
+    ...)
+{
+    va_list argptr;
+
+    MachVideoHideShowTextCursor(FALSE);
+    MachVideoClearScreen(SCREEN_ATTR);
+    i386_ScreenPosX = 0;
+    i386_ScreenPosY = 0;
+
+    PrintText("A problem has been detected and FreeLoader boot has been aborted.\n\n");
+
+    PrintText("%ld: %s\n\n", BugCode, BugCodeStrings[BugCode]);
+
+    if (File)
+    {
+        PrintText("Location: %s:%ld\n\n", File, Line);
+    }
+
+    va_start(argptr, Format);
+    PrintTextV(Format, argptr);
+    va_end(argptr);
+
+    _disable();
+    __halt();
+    for (;;);
+}
+
 void
 NTAPI
 FrLdrBugCheckEx(
@@ -178,6 +226,7 @@ FrLdrBugCheckEx(
     PCHAR File,
     ULONG Line)
 {
+    MachVideoHideShowTextCursor(FALSE);
     MachVideoClearScreen(SCREEN_ATTR);
     i386_ScreenPosX = 0;
     i386_ScreenPosY = 0;
@@ -194,6 +243,8 @@ FrLdrBugCheckEx(
     PrintText("Bug Information:\n    %p\n    %p\n    %p\n    %p\n    %p\n\n",
               BugCheckInfo[0], BugCheckInfo[1], BugCheckInfo[2], BugCheckInfo[3], BugCheckInfo[4]);
 
+    _disable();
+    __halt();
     for (;;);
 }
 
@@ -203,4 +254,3 @@ FrLdrBugCheck(ULONG BugCode)
 {
     FrLdrBugCheckEx(BugCode, 0, 0);
 }
-