[FREELDR] Separate PC beep routines out into its own file (#2347)
authorDmitry Borisov <di.sean@protonmail.com>
Fri, 14 Feb 2020 18:22:17 +0000 (00:22 +0600)
committerGitHub <noreply@github.com>
Fri, 14 Feb 2020 18:22:17 +0000 (19:22 +0100)
- Remove now unused i386rtl.c (and it doesn't contains RTL functions nowadays).
- Separate PC beep routines out into its own file.
- Also use delay function instead of BIOS interrupts.
- Improve as well the accuracy of KeStallExecutionProcessor() by using the same HW delay function.

boot/freeldr/freeldr/CMakeLists.txt
boot/freeldr/freeldr/arch/i386/i386rtl.c [deleted file]
boot/freeldr/freeldr/arch/i386/ntoskrnl.c
boot/freeldr/freeldr/arch/i386/pc/machpc.c
boot/freeldr/freeldr/arch/i386/pc/pcbeep.c [new file with mode: 0644]

index 5b32b2e..dd8bc31 100644 (file)
@@ -121,7 +121,6 @@ if(ARCH STREQUAL "i386")
         arch/i386/hwpci.c
         arch/i386/i386bug.c
         arch/i386/i386idt.c
-        arch/i386/i386rtl.c
         arch/i386/i386vid.c
         disk/scsiport.c)
 
@@ -129,6 +128,7 @@ if(ARCH STREQUAL "i386")
         list(APPEND FREELDR_ARC_SOURCE
             # FIXME: Abstract things better so we don't need to include /pc/* here
             arch/i386/pc/machpc.c       # machxbox.c depends on it
+            arch/i386/pc/pcbeep.c       # machxbox.c depends on it
             arch/i386/pc/pcdisk.c       # hwdisk.c depends on it
             arch/i386/pc/pcmem.c        # hwacpi.c/xboxmem.c depends on it
             arch/i386/xbox/machxbox.c
@@ -142,6 +142,7 @@ if(ARCH STREQUAL "i386")
     else()
         list(APPEND FREELDR_ARC_SOURCE
             arch/i386/pc/machpc.c
+            arch/i386/pc/pcbeep.c
             arch/i386/pc/pccons.c
             arch/i386/pc/pcdisk.c
             arch/i386/pc/pcmem.c
@@ -169,9 +170,9 @@ elseif(ARCH STREQUAL "amd64")
         arch/i386/hwdisk.c
         arch/i386/hwpci.c
         arch/i386/i386bug.c
-        arch/i386/i386rtl.c
         arch/i386/i386vid.c
         arch/i386/pc/machpc.c
+        arch/i386/pc/pcbeep.c
         arch/i386/pc/pccons.c
         arch/i386/pc/pcdisk.c
         arch/i386/pc/pcmem.c
diff --git a/boot/freeldr/freeldr/arch/i386/i386rtl.c b/boot/freeldr/freeldr/arch/i386/i386rtl.c
deleted file mode 100644 (file)
index e4ef701..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- *  FreeLoader
- *  Copyright (C) 1998-2003  Brian Palmer  <brianp@sginet.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <freeldr.h>
-
-void sound(int freq);
-void delay(unsigned msec);
-
-VOID PcBeep(VOID)
-{
-    sound(700);
-    delay(200);
-    sound(0);
-}
-
-void delay(unsigned msec)
-{
-    REGS        Regs;
-    unsigned    usec;
-    unsigned    msec_this;
-
-    // Int 15h AH=86h
-    // BIOS - WAIT (AT,PS)
-    //
-    // AH = 86h
-    // CX:DX = interval in microseconds
-    // Return:
-    // CF clear if successful (wait interval elapsed)
-    // CF set on error or AH=83h wait already in progress
-    // AH = status (see #00496)
-
-    // Note: The resolution of the wait period is 977 microseconds on
-    // many systems because many BIOSes use the 1/1024 second fast
-    // interrupt from the AT real-time clock chip which is available on INT 70;
-    // because newer BIOSes may have much more precise timers available, it is
-    // not possible to use this function accurately for very short delays unless
-    // the precise behavior of the BIOS is known (or found through testing)
-
-    while (msec)
-    {
-        msec_this = msec;
-
-        if (msec_this > 4000)
-        {
-            msec_this = 4000;
-        }
-
-        usec = msec_this * 1000;
-
-        Regs.b.ah = 0x86;
-        Regs.w.cx = usec >> 16;
-        Regs.w.dx = usec & 0xffff;
-        Int386(0x15, &Regs, &Regs);
-
-        msec -= msec_this;
-    }
-}
-
-void sound(int freq)
-{
-    int scale;
-
-    if (freq == 0)
-    {
-        WRITE_PORT_UCHAR((PUCHAR)0x61, READ_PORT_UCHAR((PUCHAR)0x61) & ~3);
-        return;
-    }
-
-    scale = 1193046 / freq;
-    WRITE_PORT_UCHAR((PUCHAR)0x43, 0xb6);
-    WRITE_PORT_UCHAR((PUCHAR)0x42, scale & 0xff);
-    WRITE_PORT_UCHAR((PUCHAR)0x42, scale >> 8);
-    WRITE_PORT_UCHAR((PUCHAR)0x61, READ_PORT_UCHAR((PUCHAR)0x61) | 3);
-}
-
-VOID __cdecl ChainLoadBiosBootSectorCode(
-    IN UCHAR BootDrive OPTIONAL,
-    IN ULONG BootPartition OPTIONAL)
-{
-    REGS Regs;
-
-    RtlZeroMemory(&Regs, sizeof(Regs));
-
-    /* Set the boot drive and the boot partition */
-    Regs.b.dl = (UCHAR)(BootDrive ? BootDrive : FrldrBootDrive);
-    Regs.b.dh = (UCHAR)(BootPartition ? BootPartition : FrldrBootPartition);
-
-    /*
-     * Don't stop the floppy drive motor when we are just booting a bootsector,
-     * a drive, or a partition. If we were to stop the floppy motor, the BIOS
-     * wouldn't be informed and if the next read is to a floppy then the BIOS
-     * will still think the motor is on and this will result in a read error.
-     */
-    // DiskStopFloppyMotor();
-
-    Relocator16Boot(&Regs,
-                    /* Stack segment:pointer */
-                    0x0000, 0x7C00,
-                    /* Code segment:pointer */
-                    0x0000, 0x7C00);
-}
index 3c30cad..21f8425 100644 (file)
 
 #include <ntoskrnl.h>
 
-/* For KeStallExecutionProcessor */
-#if defined(_M_IX86) || defined(_M_AMD64)
-#include <arch/pc/pcbios.h>
-#endif
-
 /* FUNCTIONS *****************************************************************/
 
 VOID
@@ -99,44 +94,5 @@ NTAPI
 KeStallExecutionProcessor(
     IN ULONG MicroSeconds)
 {
-#if defined(_M_IX86) || defined(_M_AMD64)
-    REGS Regs;
-    ULONG usec_this;
-
-    // Int 15h AH=86h
-    // BIOS - WAIT (AT,PS)
-    //
-    // AH = 86h
-    // CX:DX = interval in microseconds
-    // Return:
-    // CF clear if successful (wait interval elapsed)
-    // CF set on error or AH=83h wait already in progress
-    // AH = status (see #00496)
-
-    // Note: The resolution of the wait period is 977 microseconds on
-    // many systems because many BIOSes use the 1/1024 second fast
-    // interrupt from the AT real-time clock chip which is available on INT 70;
-    // because newer BIOSes may have much more precise timers available, it is
-    // not possible to use this function accurately for very short delays unless
-    // the precise behavior of the BIOS is known (or found through testing)
-
-    while (MicroSeconds)
-    {
-        usec_this = MicroSeconds;
-
-        if (usec_this > 4000000)
-        {
-            usec_this = 4000000;
-        }
-
-        Regs.b.ah = 0x86;
-        Regs.w.cx = usec_this >> 16;
-        Regs.w.dx = usec_this & 0xffff;
-        Int386(0x15, &Regs, &Regs);
-
-        MicroSeconds -= usec_this;
-    }
-#else
-    #error unimplemented
-#endif
+    StallExecutionProcessor(MicroSeconds);
 }
index b0b1ee9..d4259de 100644 (file)
@@ -1416,6 +1416,32 @@ PcHwIdle(VOID)
      */
 }
 
+VOID __cdecl ChainLoadBiosBootSectorCode(
+    IN UCHAR BootDrive OPTIONAL,
+    IN ULONG BootPartition OPTIONAL)
+{
+    REGS Regs;
+
+    RtlZeroMemory(&Regs, sizeof(Regs));
+
+    /* Set the boot drive and the boot partition */
+    Regs.b.dl = (UCHAR)(BootDrive ? BootDrive : FrldrBootDrive);
+    Regs.b.dh = (UCHAR)(BootPartition ? BootPartition : FrldrBootPartition);
+
+    /*
+     * Don't stop the floppy drive motor when we are just booting a bootsector,
+     * a drive, or a partition. If we were to stop the floppy motor, the BIOS
+     * wouldn't be informed and if the next read is to a floppy then the BIOS
+     * will still think the motor is on and this will result in a read error.
+     */
+    // DiskStopFloppyMotor();
+
+    Relocator16Boot(&Regs,
+                    /* Stack segment:pointer */
+                    0x0000, 0x7C00,
+                    /* Code segment:pointer */
+                    0x0000, 0x7C00);
+}
 
 /******************************************************************************/
 
diff --git a/boot/freeldr/freeldr/arch/i386/pc/pcbeep.c b/boot/freeldr/freeldr/arch/i386/pc/pcbeep.c
new file mode 100644 (file)
index 0000000..d499d8f
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * PROJECT:     FreeLoader
+ * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:     Hardware-specific beep routine
+ * COPYRIGHT:   Copyright 1998-2003 Brian Palmer (brianp@reactos.org)
+ */
+
+#include <freeldr.h>
+
+#if defined(SARCH_XBOX)
+#define CLOCK_TICK_RATE 1125000
+#else
+#define CLOCK_TICK_RATE 1193182
+#endif
+
+static VOID
+Sound(USHORT Frequency)
+{
+    USHORT Scale;
+
+    if (Frequency == 0)
+    {
+        WRITE_PORT_UCHAR((PUCHAR)0x61, READ_PORT_UCHAR((PUCHAR)0x61) & ~3);
+        return;
+    }
+
+    Scale = CLOCK_TICK_RATE / Frequency;
+    WRITE_PORT_UCHAR((PUCHAR)0x43, 0xB6);
+    WRITE_PORT_UCHAR((PUCHAR)0x42, Scale & 0xFF);
+    WRITE_PORT_UCHAR((PUCHAR)0x42, Scale >> 8);
+    WRITE_PORT_UCHAR((PUCHAR)0x61, READ_PORT_UCHAR((PUCHAR)0x61) | 3);
+}
+
+VOID PcBeep(VOID)
+{
+    Sound(700);
+    StallExecutionProcessor(100000);
+    Sound(0);
+}