logo search
несколько программ / bsp33

ПрограммаIosound

Приведем исходный текст программы IOSOUND, генерирующую звук без использования таймера (листинг 5.3.). Эта программа формирует импульсы при помощи манипуляций с разрядом 1 порта 61h.

Листинг 5.3. Файлiosound\iosound.с

// =====================================================

// Генерация звукового сигнала через порты таймера

//

// (C) Фролов А.В, 1997

//

// E-mail: frolov@glas.apc.org

// WWW: http://www.glasnet.ru/~frolov

// или

// http://www.dials.ccas.ru/frolov

// =====================================================

#include <stdio.h>

#include <conio.h>

#include <dos.h>

#define FREQUENCY 200

#define CYCLES 30000

int main(void)

{

// Во время генерации звука прерывания должны

// быть запрещены.

_disable();

_asm

{

// Загружаем количество циклов - периодов

// генерируемых импульсов

mov dx, CYCLES

// Отключаем громкоговоритель от таймера

in al, 61h

and al, 0feh

// Цикл формирования периода

sound_cycle:

// Формируем первый полупериод, подаем

// на громкоговоритель уровень 1

or al, 2

out 61h, al

// Формируем задержку

mov cx, FREQUENCY

first: loop first

// Формируем второй полупериод, подаем

// на громкоговоритель уровень 0

and al, 0fdh

out 61h, al

// Формируем задержку

mov cx, FREQUENCY

second: loop second

// Если сформированы не все периоды, переходим

// к формированию следующего периода.

dec dx

jnz sound_cycle

}

// Разрешаем прерывания

_enable();

// Выключаем громкоговоритель

outp(0x61, inp(0x61) & 0xfc);

return 0;

}

Так как в программе IOSOUNDдля формирования полупериодов используется задержка с помощью команды LOOP, высота генерируемого тона будет зависеть от производительности системы.

Такой зависимости можно избежать, если перед началом работы измерять производительность и соответствующим образом корректировать константу, загружаемую в регистр CX перед вызовом команды LOOP. Измерение производительности лучше всего выполнять с помощью таймера, определяя время выполнения команды LOOP.