[NTOS:HEADLESS]
[reactos.git] / reactos / ntoskrnl / ex / hdlsterm.c
index 20c7134..b1c0ff0 100644 (file)
@@ -6,16 +6,16 @@
  * PROGRAMMERS:     ReactOS Portable Systems Group
  */
 
-/* INCLUDES ******************************************************************/
+/* INCLUDES *******************************************************************/
 
 #include <ntoskrnl.h>
 #include <debug.h>
 
-/* GLOBALS *******************************************************************/
+/* GLOBALS ********************************************************************/
 
 PHEADLESS_GLOBALS HeadlessGlobals;
 
-/* FUNCTIONS *****************************************************************/
+/* FUNCTIONS ******************************************************************/
 
 FORCEINLINE
 KIRQL
@@ -38,7 +38,7 @@ HdlspAcquireGlobalLock(VOID)
 
 FORCEINLINE
 VOID
-HdlspReleaselobalLock(IN KIRQL OldIrql)
+HdlspReleaseGlobalLock(IN KIRQL OldIrql)
 {
     /* Only release the lock if we aren't bugchecking */
     if (OldIrql != 0xFF)
@@ -56,12 +56,93 @@ NTAPI
 HdlspSendStringAtBaud(IN PUCHAR String)
 {
     /* Send every byte */
-    while (*String++ != ANSI_NULL)
+    while (*String != ANSI_NULL)
     {
-        InbvPortPutByte(HeadlessGlobals->TerminalPort, *String);
+        InbvPortPutByte(HeadlessGlobals->TerminalPort, *String++);
     }
 }
 
+VOID
+NTAPI
+HdlspPutData(IN PUCHAR Data,
+             IN ULONG DataSize)
+{
+    ULONG i;
+    for (i = 0; i < DataSize; i++)
+    {
+        InbvPortPutByte(HeadlessGlobals->TerminalPort, Data[i]);
+    }
+}
+
+VOID
+NTAPI
+HdlspPutString(IN PUCHAR String)
+{
+    PUCHAR Dest = HeadlessGlobals->TmpBuffer;
+    UCHAR Char = 0;
+
+    /* Scan each character */
+    while (*String != ANSI_NULL)
+    {
+        /* Check for rotate, send existing buffer and restart from where we are */
+        if (Dest >= &HeadlessGlobals->TmpBuffer[79])
+        {
+            HeadlessGlobals->TmpBuffer[79] = ANSI_NULL;
+            HdlspSendStringAtBaud(HeadlessGlobals->TmpBuffer);
+            Dest = HeadlessGlobals->TmpBuffer;
+        }
+        else
+        {
+            /* Get the current character and check for special graphical chars */
+            Char = *String;
+            if (Char & 0x80)
+            {
+                switch (Char)
+                {
+                    case 0xB0: case 0xB3: case 0xBA:
+                        Char = '|';
+                        break;
+                    case 0xB1: case 0xDC: case 0xDD: case 0xDE: case 0xDF:
+                        Char = '%';
+                        break;
+                    case 0xB2: case 0xDB:
+                        Char = '#';
+                        break;
+                    case 0xA9: case 0xAA: case 0xBB: case 0xBC: case 0xBF:
+                    case 0xC0: case 0xC8: case 0xC9: case 0xD9: case 0xDA:
+                        Char = '+';
+                        break;
+                    case 0xC4:
+                        Char = '-';
+                        break;
+                    case 0xCD:
+                        Char = '=';
+                        break;
+                }
+            }
+
+            /* Anything else must be Unicode */
+            if (Char & 0x80)
+            {
+                /* Can't do Unicode yet */
+                UNIMPLEMENTED;
+            }
+            else
+            {
+                /* Add the modified char to the temporary buffer */
+                *Dest++ = Char;
+            }
+            
+            /* Check the next char */
+            String++;
+        }
+    }
+
+    /* Finish and send */
+    *Dest = ANSI_NULL;
+    HdlspSendStringAtBaud(HeadlessGlobals->TmpBuffer);
+}
+
 NTSTATUS
 NTAPI
 HdlspEnableTerminal(IN BOOLEAN Enable)
@@ -138,7 +219,7 @@ HeadlessInit(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
     HeadlessGlobals->IsMMIODevice = HeadlessBlock->IsMMIODevice;
     HeadlessGlobals->TerminalType = HeadlessBlock->TerminalType;
     HeadlessGlobals->SystemGUID = HeadlessBlock->SystemGUID;
-    DPRINT1("EMS on Port %d (0x%lx) at %d bps\n",
+    DPRINT1("EMS on Port %lu (0x%p) at %lu bps\n",
              HeadlessGlobals->TerminalPortNumber,
              HeadlessGlobals->TerminalPortAddress,
              HeadlessGlobals->TerminalBaudRate);
@@ -169,87 +250,6 @@ HeadlessInit(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
     HdlspEnableTerminal(TRUE);
 }
 
-VOID
-NTAPI
-HdlspPutData(IN PUCHAR Data,
-             IN ULONG DataSize)
-{
-    ULONG i;
-    for (i = 0; i < DataSize; i++)
-    {
-        InbvPortPutByte(HeadlessGlobals->TerminalPort, Data[i]++);
-    }
-}
-
-VOID
-NTAPI
-HdlspPutString(IN PUCHAR String)
-{
-       PUCHAR Dest = HeadlessGlobals->TmpBuffer;
-       UCHAR Char = 0;
-
-       /* Scan each character */
-       while (*String != ANSI_NULL)
-       {
-               /* Check for rotate, send existing buffer and restart from where we are */
-               if (Dest >= &HeadlessGlobals->TmpBuffer[79])
-               {
-                       HeadlessGlobals->TmpBuffer[79] = ANSI_NULL;
-                       HdlspSendStringAtBaud(HeadlessGlobals->TmpBuffer);
-                       Dest = HeadlessGlobals->TmpBuffer;
-               }
-               else
-               {
-                       /* Get the current character and check for special graphical chars */
-                       Char = *String;
-                       if (Char & 0x80)
-                       {
-                               switch (Char)
-                               {
-                                       case 0xB0: case 0xB3: case 0xBA:
-                                               Char = '|';
-                                               break;
-                                       case 0xB1: case 0xDC: case 0xDD: case 0xDE: case 0xDF:
-                                               Char = '%';
-                                               break;
-                                       case 0xB2: case 0xDB:
-                                               Char = '#';
-                                               break;
-                                       case 0xA9: case 0xAA: case 0xBB: case 0xBC: case 0xBF:
-                                       case 0xC0: case 0xC8: case 0xC9: case 0xD9: case 0xDA:
-                                               Char = '+';
-                                               break;
-                                       case 0xC4:
-                                               Char = '-';
-                                               break;
-                                       case 0xCD:
-                                               Char = '=';
-                                               break;
-                                       }
-                       }
-
-                       /* Anything else must be Unicode */
-                       if (Char & 0x80)
-                       {
-                               /* Can't do Unicode yet */
-                               UNIMPLEMENTED;
-                       }
-                       else
-                       {
-                               /* Add the modified char to the temporary buffer */
-                               *Dest++ = Char;
-                       }
-                       
-                       /* Check the next char */
-                       String++;
-               }
-       }
-
-       /* Finish and send */
-       *Dest = ANSI_NULL;
-       HdlspSendStringAtBaud(HeadlessGlobals->TmpBuffer);
-}
-
 NTSTATUS
 NTAPI
 HdlspDispatch(IN HEADLESS_CMD Command,
@@ -262,9 +262,10 @@ HdlspDispatch(IN HEADLESS_CMD Command,
     PHEADLESS_RSP_QUERY_INFO HeadlessInfo;
     PHEADLESS_CMD_PUT_STRING PutString;
     PHEADLESS_CMD_ENABLE_TERMINAL EnableTerminal;
+    PHEADLESS_RSP_GET_BYTE GetByte;
     NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
     ASSERT(HeadlessGlobals != NULL);
-//     ASSERT(HeadlessGlobals->PageLockHandle != NULL);
+    // ASSERT(HeadlessGlobals->PageLockHandle != NULL);
 
     /* Ignore non-reentrant commands */
     if ((Command != HeadlessCmdAddLogEntry) &&
@@ -276,20 +277,20 @@ HdlspDispatch(IN HEADLESS_CMD Command,
 
         if (HeadlessGlobals->ProcessingCmd)
         {
-            HdlspReleaselobalLock(OldIrql);
+            HdlspReleaseGlobalLock(OldIrql);
             return STATUS_UNSUCCESSFUL;
         }
 
         /* Don't allow these commands next time */
         HeadlessGlobals->ProcessingCmd = TRUE;
-        HdlspReleaselobalLock(OldIrql);
+        HdlspReleaseGlobalLock(OldIrql);
     }
 
     /* Handle each command */
     switch (Command)
     {
         case HeadlessCmdEnableTerminal:
-
+        {
             /* Make sure the caller passed valid data */
             if (!(InputBuffer) ||
                 (InputBufferSize != sizeof(*EnableTerminal)))
@@ -303,12 +304,13 @@ HdlspDispatch(IN HEADLESS_CMD Command,
             EnableTerminal = InputBuffer;
             Status = HdlspEnableTerminal(EnableTerminal->Enable);
             break;
+        }
 
-               case HeadlessCmdCheckForReboot:
-                       break;
-
-               case HeadlessCmdPutString:
+        case HeadlessCmdCheckForReboot:
+            break;
 
+        case HeadlessCmdPutString:
+        {
             /* Validate the existence of an input buffer */
             if (!InputBuffer)
             {
@@ -327,33 +329,85 @@ HdlspDispatch(IN HEADLESS_CMD Command,
             /* Return success either way */
             Status = STATUS_SUCCESS;
             break;
+        }
 
-               case HeadlessCmdClearDisplay:
-                       break;
-               case HeadlessCmdClearToEndOfDisplay:
-                       break;
-               case HeadlessCmdClearToEndOfLine:
-                       break;
-               case HeadlessCmdDisplayAttributesOff:
-                       break;
-               case HeadlessCmdDisplayInverseVideo:
-                       break;
-               case HeadlessCmdSetColor:
-                       break;
-               case HeadlessCmdPositionCursor:
-                       break;
-               case HeadlessCmdTerminalPoll:
-                       break;
-               case HeadlessCmdGetByte:
-                       break;
-               case HeadlessCmdGetLine:
-                       break;
-               case HeadlessCmdStartBugCheck:
-                       break;
-               case HeadlessCmdDoBugCheckProcessing:
-                       break;
-               case HeadlessCmdQueryInformation:
+        case HeadlessCmdClearDisplay:
+        {
+            /* Send the VT100 clear screen command if the terminal is enabled */
+            if (HeadlessGlobals->TerminalEnabled)
+            {
+                HdlspSendStringAtBaud((PUCHAR)"\033[2J");
+            }
+
+            /* Return success either way */
+            Status = STATUS_SUCCESS;
+            break;
+        }
 
+        case HeadlessCmdClearToEndOfDisplay:
+            break;
+        case HeadlessCmdClearToEndOfLine:
+            break;
+        case HeadlessCmdDisplayAttributesOff:
+            break;
+        case HeadlessCmdDisplayInverseVideo:
+            break;
+        case HeadlessCmdSetColor:
+            break;
+        case HeadlessCmdPositionCursor:
+            break;
+        case HeadlessCmdTerminalPoll:
+            break;
+
+        case HeadlessCmdGetByte:
+        {
+            /* Make sure the caller passed valid data */
+            if (!(OutputBuffer) ||
+                !(OutputBufferSize) ||
+                (*OutputBufferSize < sizeof(*GetByte)))
+            {
+                DPRINT1("Invalid buffer\n");
+                Status = STATUS_INVALID_PARAMETER;
+                break;
+            }
+
+            /* Make sure the terminal is enabled */
+            GetByte = OutputBuffer;
+            if (HeadlessGlobals->TerminalEnabled)
+            {
+                /* Poll if something is on the wire */
+                if (InbvPortPollOnly(HeadlessGlobals->TerminalPort))
+                {
+                    /* If so, read it */
+                    InbvPortGetByte(HeadlessGlobals->TerminalPort,
+                                    &GetByte->Value);
+                }
+                else
+                {
+                    /* Nothing is there, return 0 */
+                    GetByte->Value = 0;
+                }
+            }
+            else
+            {
+                /* Otherwise return nothing */
+                GetByte->Value = 0;
+            }
+
+            /* Return success either way */
+            Status = STATUS_SUCCESS;
+            break;
+        }
+
+        case HeadlessCmdGetLine:
+            break;
+        case HeadlessCmdStartBugCheck:
+            break;
+        case HeadlessCmdDoBugCheckProcessing:
+            break;
+
+        case HeadlessCmdQueryInformation:
+        {
             /* Make sure the caller passed valid data */
             if (!(OutputBuffer) ||
                 !(OutputBufferSize) ||
@@ -368,7 +422,7 @@ HdlspDispatch(IN HEADLESS_CMD Command,
             HeadlessInfo = OutputBuffer;
             HeadlessInfo->PortType = HeadlessSerialPort;
             HeadlessInfo->Serial.TerminalAttached = TRUE;
-            HeadlessInfo->Serial.UsedBiosSettings = HeadlessGlobals->UsedBiosSettings;
+            HeadlessInfo->Serial.UsedBiosSettings = HeadlessGlobals->UsedBiosSettings != 0;
             HeadlessInfo->Serial.TerminalBaudRate = HeadlessGlobals->TerminalBaudRate;
             HeadlessInfo->Serial.TerminalType = HeadlessGlobals->TerminalType;
 
@@ -392,12 +446,15 @@ HdlspDispatch(IN HEADLESS_CMD Command,
             /* All done */
             Status = STATUS_SUCCESS;
             break;
-               case HeadlessCmdAddLogEntry:
-                       break;
-               case HeadlessCmdDisplayLog:
-                       break;
-        case HeadlessCmdSetBlueScreenData:
+        }
 
+        case HeadlessCmdAddLogEntry:
+            break;
+        case HeadlessCmdDisplayLog:
+            break;
+
+        case HeadlessCmdSetBlueScreenData:
+        {
             /* Validate the existence of an input buffer */
             if (!InputBuffer)
             {
@@ -409,12 +466,15 @@ HdlspDispatch(IN HEADLESS_CMD Command,
             UNIMPLEMENTED;
             Status = STATUS_SUCCESS;
             break;
-               case HeadlessCmdSendBlueScreenData:
-                       break;
-               case HeadlessCmdQueryGUID:
-                       break;
-               case HeadlessCmdPutData:
+        }
+
+        case HeadlessCmdSendBlueScreenData:
+            break;
+        case HeadlessCmdQueryGUID:
+            break;
 
+        case HeadlessCmdPutData:
+        {
             /* Validate the existence of an input buffer */
             if (!(InputBuffer) || !(InputBufferSize))
             {
@@ -433,6 +493,7 @@ HdlspDispatch(IN HEADLESS_CMD Command,
             /* Return success either way */
             Status = STATUS_SUCCESS;
             break;
+        }
 
         default:
             break;
@@ -483,6 +544,7 @@ HeadlessDispatch(IN HEADLESS_CMD Command,
 
             RtlZeroMemory(OutputBuffer, *OutputBufferSize);
         }
+
         return STATUS_SUCCESS;
     }