From 747d50c52e9f4e28060032513cfbe52be8f48776 Mon Sep 17 00:00:00 2001 From: Dmitry Borisov Date: Sat, 15 Feb 2020 00:22:17 +0600 Subject: [PATCH] [FREELDR] Separate PC beep routines out into its own file (#2347) - 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 | 5 +- boot/freeldr/freeldr/arch/i386/i386rtl.c | 117 --------------------- boot/freeldr/freeldr/arch/i386/ntoskrnl.c | 46 +------- boot/freeldr/freeldr/arch/i386/pc/machpc.c | 26 +++++ boot/freeldr/freeldr/arch/i386/pc/pcbeep.c | 39 +++++++ 5 files changed, 69 insertions(+), 164 deletions(-) delete mode 100644 boot/freeldr/freeldr/arch/i386/i386rtl.c create mode 100644 boot/freeldr/freeldr/arch/i386/pc/pcbeep.c diff --git a/boot/freeldr/freeldr/CMakeLists.txt b/boot/freeldr/freeldr/CMakeLists.txt index 5b32b2e74eb..dd8bc31703e 100644 --- a/boot/freeldr/freeldr/CMakeLists.txt +++ b/boot/freeldr/freeldr/CMakeLists.txt @@ -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 index e4ef701da52..00000000000 --- a/boot/freeldr/freeldr/arch/i386/i386rtl.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * FreeLoader - * Copyright (C) 1998-2003 Brian Palmer - * - * 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 - -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); -} diff --git a/boot/freeldr/freeldr/arch/i386/ntoskrnl.c b/boot/freeldr/freeldr/arch/i386/ntoskrnl.c index 3c30cad41ce..21f8425d6c5 100644 --- a/boot/freeldr/freeldr/arch/i386/ntoskrnl.c +++ b/boot/freeldr/freeldr/arch/i386/ntoskrnl.c @@ -10,11 +10,6 @@ #include -/* For KeStallExecutionProcessor */ -#if defined(_M_IX86) || defined(_M_AMD64) -#include -#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); } diff --git a/boot/freeldr/freeldr/arch/i386/pc/machpc.c b/boot/freeldr/freeldr/arch/i386/pc/machpc.c index b0b1ee9694b..d4259de92aa 100644 --- a/boot/freeldr/freeldr/arch/i386/pc/machpc.c +++ b/boot/freeldr/freeldr/arch/i386/pc/machpc.c @@ -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 index 00000000000..d499d8f50ca --- /dev/null +++ b/boot/freeldr/freeldr/arch/i386/pc/pcbeep.c @@ -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 + +#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); +} -- 2.17.1