mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
[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.
This commit is contained in:
parent
571407c7d2
commit
747d50c52e
5 changed files with 69 additions and 164 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -10,11 +10,6 @@
|
|||
|
||||
#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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
|
39
boot/freeldr/freeldr/arch/i386/pc/pcbeep.c
Normal file
39
boot/freeldr/freeldr/arch/i386/pc/pcbeep.c
Normal file
|
@ -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);
|
||||
}
|
Loading…
Reference in a new issue