Skip to content

Instantly share code, notes, and snippets.

@HoShiMin
Last active September 2, 2015 20:45
Show Gist options
  • Save HoShiMin/34fa7f492d99d4b07978 to your computer and use it in GitHub Desktop.
Save HoShiMin/34fa7f492d99d4b07978 to your computer and use it in GitHub Desktop.
Удобный модуль-обёртка для работы с системной пищалкой средствами WinRing0
unit BeeperWrapper;
interface
uses
WinRing0;
{
Подробности здесь:
http://wiki.osdev.org/PIT
http://wiki.osdev.org/PC_Speaker
}
function InitializeBeeper: LongWord;
function DeinitializeBeeper: Boolean;
procedure SetBeeperOut;
procedure SetBeeperIn;
procedure StartBeeper;
procedure StopBeeper;
procedure SetBeeperRegime;
procedure SetBeeperDivider(Value: Word);
procedure SetBeeperFrequency(Value: Single);
implementation
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function InitializeBeeper: LongWord;
begin
InitializeOls;
Result := GetDLLStatus;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function DeinitializeBeeper: Boolean;
begin
Result := DeinitializeOls;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure SetBeeperOut;
var
Value: Byte;
begin
{
; Взводим 1 бит, отвечающий за положение мембраны из порта 61h - подаём напряжение:
in al, 61h
or al, 00000010b
out 61h, al
}
Value := ReadIoPortByte($61);
Value := Value or 2;
WriteIoPortByte($61, Value);
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure SetBeeperIn;
var
Value: Byte;
begin
{
; Сбрасываем 1 бит, отвечающий за положение мембраны из порта 61h - снимаем напряжение:
in al, 61h
and al, 11111101b
out 61h, al
}
Value := ReadIoPortByte($61);
Value := Value and 253;
WriteIoPortByte($61, Value);
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure StartBeeper;
var
Value: Byte;
begin
{
; Взводим 2 бита, отвечающие за включенность пищалки из порта 61h:
in al, 61h
or al, 00000011b
out 61h, al
}
Value := ReadIoPortByte($61);
Value := Value or 3;
WriteIoPortByte($61, Value);
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure StopBeeper;
var
Value: Byte;
begin
{
; Сбрасываем первые два бита в порте 61h, отвечающие за включенность пищалки:
in al, 61h
and al, 11111100b
out 61h, al
}
Value := ReadIoPortByte($61);
Value := Value and 252;
WriteIoPortByte($61, Value);
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure SetBeeperRegime;
const
InitializationValue: Byte = $0B6;
begin
{
; Инициализируем пищалку:
mov al, $0B6h ; 0B6h = 10 11 011 0
10 = номер канала, которым мы будем управлять (10b = второй канал)
11 = тип операции (11b = чтение/запись сначала младшего, а потом старшего байта)
011 = режим работы канала (011b = генератор прямоугольных импульсов (основной режим))
0 = формат счетчика (0 = 16-разрядное число от 0 до 0FFFFh)
out 43h, al
}
WriteIoPortByte($43, InitializationValue);
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure SetBeeperDivider(Value: Word);
begin
WriteIoPortByte($42, Byte(Value)); // Младшая часть
WriteIoPortByte($42, Byte(Pointer(NativeUInt(@Value) + 1)^)); // Старшая часть
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure SetBeeperFrequency(Value: Single);
begin
SetBeeperDivider(Word(Round(1193180 / Value)));
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment