Программирование на Си в MS-DOS

Всё, что касается программирования на старых языках или для старых систем

Программирование на Си в MS-DOS

Сообщение IBMForever » 29 июл 2026, 09:51

Тема по программированию на языке Си в среде MS-DOS.
Выкладываем программы, предалгаем задачи, рассматриваем способы программирования на языке Си.
Основной компилятор Borland Turbo C v2.01. который можно скачать тут же.
Системные требования: IBM PC XT\AT 16 битные компьютеры с 1 мб ОЗУ.
Помимо компиляторов от фирмы Borland есть ещё от Майкрасофта и ANSI.
Шапка темы будет периодически пополнятся полезной информацией.
32 стандартных ключевых слова ANSI C (89)
 Развернуть:
Типы данных и их модификаторы:
char — символьный тип.
int — целочисленный тип.
float — тип с плавающей точкой.
double — плавающая точка двойной точности.
short — короткое целое.
long — длинное целое.
signed — знаковый тип.
unsigned — беззнаковый тип.
void — отсутствие значения (пустой тип).
Управление потоком выполнения (ветвления и циклы):
if — условный оператор.
else — альтернативная ветка условного оператора.
switch — оператор многовариантного выбора.
case — вариант в операторе switch.
default — ветка по умолчанию в операторе switch.
for — цикл с параметром.
while — цикл с предусловием.
do — цикл с постусловием.
break — досрочный выход из цикла или switch.
continue — переход к следующей итерации цикла.
goto — оператор безусловного перехода.
return — возврат из функции.
Классы памяти и спецификаторы:
auto — автоматическая локальная переменная.
register — предложение хранить переменную в регистре процессора.
static — статическая переменная (сохраняет значение).
extern — объявление внешней переменной.
const — объявление константы (запрет изменения).
volatile — указание компилятору не оптимизировать чтение переменной.
Сложные типы и структуры:
struct — объявление структуры.
union — объявление объединения.
enum — перечисляемый тип.
typedef — создание псевдонима для существующего типа.
Определение размера:
sizeof — операция вычисления размера объекта или типа в байтах.
Последний раз редактировалось IBMForever 29 июл 2026, 10:17, всего редактировалось 1 раз.
Аватара пользователя
IBMForever
Мастер Даунгрейда
 
Сообщения: 301
Зарегистрирован: 24 авг 2022, 00:23
Железо: IBM PC 286 AT

Re: Программирование на Си в MS-DOS

Сообщение luzga » 29 июл 2026, 13:09

Я не думаю, что мой ответ Оффтопик...
Сейчас всё делает компьютерный ассистент, зовут его Гугл. Задаешь ему вопрос и получаешь ответ. Ответ этот, не как раньше в виде ссылок, а код - действующий.
Называют такое программирование, модным словом, ВайбКодинг!
Вопрос нужно грамотно задавать - это первое и самое важное, иначе не получишь ответ, а получишь ссылки.
Пример вопроса:
C++ Win32 SendMessage() HWND_BROADCAST перезагрузка обновление usb диска после записи
Пример вопроса:
C++ резидентная TSR программа использующая DOS функцию 0x31
Пример вопроса:
C++ MFC CString извлечь из ответа HTTP-заголовка Set-Cookie: и добавить в массив VC 6.0
Аватара пользователя
luzga
Мастер Даунгрейда
 
Сообщения: 478
Зарегистрирован: 04 сен 2025, 19:35

Re: Программирование на Си в MS-DOS

Сообщение iAPX286 » 29 июл 2026, 13:46

IBMForever писал(а):Помимо компиляторов от фирмы Borland есть ещё от Майкрасофта и ANSI.

Есть такой интересный список: https://www.edm2.com/index.php/DOS_Implementations_of_C
Аватара пользователя
iAPX286
Опытный даунгрейдер
 
Сообщения: 34
Зарегистрирован: 09 фев 2026, 01:59

Re: Программирование на Си в MS-DOS

Сообщение Prizrak » 31 июл 2026, 20:35

Подскажите, пожалуйста, коллеги: как можно в C или C++ под DOS наладить запуск нескольких программ одновременно за счет программных прерываний, если конечно это предусмотрено? :geek:
Аватара пользователя
Prizrak
Мастер Даунгрейда
 
Сообщения: 275
Зарегистрирован: 09 окт 2024, 19:20
Откуда: Минск
Железо: Ноутбук HP, планшетник Android

Re: Программирование на Си в MS-DOS

Сообщение Prizrak » 31 июл 2026, 20:49

Я хочу попытаться написать модуль к своей музыкальной программке, чтобы он позволял разыгрывать партитуру, чтобы всем было понятнее... :roll:
Аватара пользователя
Prizrak
Мастер Даунгрейда
 
Сообщения: 275
Зарегистрирован: 09 окт 2024, 19:20
Откуда: Минск
Железо: Ноутбук HP, планшетник Android

Re: Программирование на Си в MS-DOS

Сообщение Prizrak » 01 авг 2026, 00:01

Пока на Turbo Pascal'е получилась дурацкая программка, которая делает забавные ремиксы в электронном стиле из партитуры... :D Там надо прописывать дополнительный параметр количества партий в ноте - и она играет их подряд за очень короткие промежутки времени. Электронная музыка получается даже из старых романсов, как ни странно. Это не то что надо, но тоже может иметь применение... :roll: (Итого, делаем вывод: ремикс - это партитура, сыгранная последовательно по голосам от такта к такту, обычно естественно синтезатором. Я сам слегка шокирован этим изобретением... Под DOS это реализуется, как ни странно, проще некуда...)
Последний раз редактировалось Prizrak 01 авг 2026, 00:22, всего редактировалось 1 раз.
Аватара пользователя
Prizrak
Мастер Даунгрейда
 
Сообщения: 275
Зарегистрирован: 09 окт 2024, 19:20
Откуда: Минск
Железо: Ноутбук HP, планшетник Android

Re: Программирование на Си в MS-DOS

Сообщение IBMForever » 01 авг 2026, 04:41

Prizrak писал(а):Пока на Turbo Pascal'е получилась дурацкая программка, которая делает забавные ремиксы в электронном стиле из партитуры... :D Там надо прописывать дополнительный параметр количества партий в ноте - и она играет их подряд за очень короткие промежутки времени. Электронная музыка получается даже из старых романсов, как ни странно. Это не то что надо, но тоже может иметь применение... :roll: (Итого, делаем вывод: ремикс - это партитура, сыгранная последовательно по голосам от такта к такту, обычно естественно синтезатором. Я сам слегка шокирован этим изобретением... Под DOS это реализуется, как ни странно, проще некуда...)

Программируйте на чем удобнее, главное чтобы программу сюда или в тему по С++ выложили.
Аватара пользователя
IBMForever
Мастер Даунгрейда
 
Сообщения: 301
Зарегистрирован: 24 авг 2022, 00:23
Железо: IBM PC 286 AT

Re: Программирование на Си в MS-DOS

Сообщение Prizrak » 01 авг 2026, 08:58

Да нет, мне-то принципиально... :roll: Я же взял на себя задачу освоить C. Мне интересно, какие там конструкции для параллельных процессов есть. Я так понимаю, там должна быть какая-то управляющая конструкция конвееризации, указывающая что несколько функций надо исполнять одновременно. Но вот какая?
Последний раз редактировалось Prizrak 01 авг 2026, 09:15, всего редактировалось 1 раз.
Аватара пользователя
Prizrak
Мастер Даунгрейда
 
Сообщения: 275
Зарегистрирован: 09 окт 2024, 19:20
Откуда: Минск
Железо: Ноутбук HP, планшетник Android

Re: Программирование на Си в MS-DOS

Сообщение IBMForever » 01 авг 2026, 09:11

Prizrak писал(а):Да нет, мне-то принципиально... :roll: Я же взял на себя задачу освоить C. Мне интересно, какие там конструкции для параллельных процессов есть.

У нас одинаковые задачи. Единственное что могу сказать, так это то что Си не поддерживает Protected mode(защищенный режим 386 и выше).
Лично для меня это не критично, чем меньше ключевых слов учить, тем лучше.
В Си их 32, а в версии 3.1 С++ в два раза больше и синтаксис библиотек и операторов другой.
Аватара пользователя
IBMForever
Мастер Даунгрейда
 
Сообщения: 301
Зарегистрирован: 24 авг 2022, 00:23
Железо: IBM PC 286 AT

Re: Программирование на Си в MS-DOS

Сообщение luzga » 01 авг 2026, 09:25

Prizrak писал(а):Подскажите, пожалуйста, коллеги: как можно в C или C++ под DOS наладить запуск нескольких программ одновременно за счет программных прерываний, если конечно это предусмотрено?


DOS, DOS32 - защищенный режим, через расширитель DOS4GW/PmodeW, является однозадачной ОС (операционной системой).
Не поддерживает многопоточность.
Многопоточность в DOS32 возможна только через кооперативную многозадачность, ручное переключение контекста или написание собственного прерываемого таймера, но это нестабильно.

Prizrak писал(а):Я хочу попытаться написать модуль к своей музыкальной программке, чтобы он позволял разыгрывать партитуру, чтобы всем было понятнее...

Мне, с точки зрения программиста, непонятно.
Нужно знать, что конкретно вы планируете делать, тогда станет яснее.
Последний раз редактировалось luzga 01 авг 2026, 09:26, всего редактировалось 1 раз.
Аватара пользователя
luzga
Мастер Даунгрейда
 
Сообщения: 478
Зарегистрирован: 04 сен 2025, 19:35

Re: Программирование на Си в MS-DOS

Сообщение KPG » 01 авг 2026, 09:29

IBMForever писал(а):Лично для меня это не критично, чем меньше ключевых слов учить, тем лучше.
В Си их 32, а в версии 3.1 С++ в два раза больше и синтаксис библиотек и операторов другой.

Не важно сколько и каких ключевых слов в том или ином языке (Си, к примеру, расширяется с помощью библиотек и их слов), а важнее какую задачу Вы планируете решить с помощью конкретного языка!

P.S. В типичной Форт- системе слов от 300-400... и более, но это не показатель не пригодности его к использованию для решения каких то "абстрактных" задач (создатели стандарта Форт языка - 83г, 94 ANSI) их внесли в список.
Последний раз редактировалось KPG 01 авг 2026, 09:33, всего редактировалось 2 раз(а).
KPG
Мастер Даунгрейда
 
Сообщения: 514
Зарегистрирован: 21 окт 2015, 20:53

Re: Программирование на Си в MS-DOS

Сообщение Prizrak » 01 авг 2026, 11:22

luzga, я не знаю, что Вы понимаете в музыке - поэтому объясню просто... Есть музыкальное произведение - к примеру, старинный романс, состоящий из партии голоса и партии фортепиано. Обе партии, в нормальном случае, должны играться параллельно, чтобы одновременно исполнялась и соответвующая нота из партии голоса, которую должен брать певец, выпевая какой-то слог текста песни, если бы это было живое исполнение, и соответствующая нота или аккорд на фортепиано, которое играет в такт голосу певца. Это надо изобразить в программе, чтобы на спикере PC проигрывались 2 или 3 или 4 ноты одновременно.

Я не знаю, возможно ли это на C и работает ли в таком режиме среднестатистический спикер - поэтому и спрашиваю. Чтобы совсем просто: у меня сейчас в программе монофония, а надо попробовать сделать полифонию.
Аватара пользователя
Prizrak
Мастер Даунгрейда
 
Сообщения: 275
Зарегистрирован: 09 окт 2024, 19:20
Откуда: Минск
Железо: Ноутбук HP, планшетник Android

Re: Программирование на Си в MS-DOS

Сообщение luzga » 01 авг 2026, 13:50

Prizrak, я вас понял.
Попробуйте следующую программу.
Программа реализует двухканальный псевдополифонический бипер, два
логических процесса или голоса, играющих разные ноты одновременно
за счет перехвата системного таймера Irq 0, Int 8.
 Развернуть: Псевдополифония
Код: Выделить всё
// Программа параллельного запуска двух разных частот полифонии.
// Голос 1: 440 Гц (нота Ля)
// Голос 2: 554 Гц, нота До-диез
// Звук воспроизведения через PC Speaker (Динамик ПК).
//
// Двухканальная псевдополифония. Два логических процесса или
// голоса, играющих разные ноты одновременно за счет перехвата
// системного таймера irq 0, int 8.

#include <dos.h>
#include <conio.h>
#include <stdio.h>

// Старый вектор прерывания таймера.
void interrupt (*old_timer)(...);

// Структура для процесса, голоса воспроизведения.
typedef struct {
unsigned long duration;   // Длительность в тиках таймера.
unsigned frequency;      // Частота звука Гц.
unsigned long counter;   // Текущий счетчик смены фазы.
int active;            // Флаг активности канала.
} Voice;

Voice voice1 = {0, 0, 0, 0};
Voice voice2 = {0, 0, 0, 0};

// Текущая, выводимая частота на динамик.
unsigned current_freq;
int toggle_channel;

void interrupt new_timer(...)
{
   // Функция, устанавливает новое прерывание таймера,
   // вызывается 18.2 раза в секунду или чаще при перенастройке.

   // Вызвать оригинальный, системный обработчик DOS,
   // чтобы часы не отставали.
   old_timer();

   // Чередование каналов.
   if (voice1.active && voice2.active) {
      toggle_channel = !toggle_channel;
      current_freq = toggle_channel ? voice1.frequency : voice2.frequency;
   }
   else if (voice1.active)
      current_freq = voice1.frequency;
   else if (voice2.active)
      current_freq = voice2.frequency;
   else
      current_freq = 0;

   // Управление динамиком.
   if (current_freq > 0)
   {
      unsigned div = 1193180L / current_freq;
      outportb(0x43, 0xB6); // Канал 2, режим 3, меандр.
      outportb(0x42, div & 0xFF);
      outportb(0x42, div >> 8);

      // Включить динамик, биты 0 и 1 порта 0x61
      outportb(0x61, inportb(0x61) | 3);
   }
   else
   {
      // Выключить динамик.
      outportb(0x61, inportb(0x61) & 0xFC);
   }

   // Уменьшить счетчики длительности.
   if (voice1.active)
   {
      if (--voice1.duration == 0)
         voice1.active = 0;
   }
   if (voice2.active)
   {
      if (--voice2.duration == 0)
         voice2.active = 0;
   }
}

void play_voice(int channel, unsigned freq, unsigned long dur)
{
   // Функция запуска ноты
   // в первом или втором процессе...

   disable(); // Запретить прерывания при изменении общей структуры.
   if (1 == channel)
   {
      voice1.frequency = freq;
      voice1.duration = dur;
      voice1.active = 1;
   }
   else
   {
      voice2.frequency = freq;
      voice2.duration = dur;
      voice2.active = 1;
   }
   enable();
}

int main()
{
   clrscr();
   printf("PC Speaker Ї®«Ёд®­Ёп. „«п ўл室 , ­ ¦¬ЁвҐ «оЎго Є« ўЁиг...\n");

   // Сохранить старый и установить новый
   // обработчик прерывания таймера.
   old_timer = getvect(8);
   setvect(8, new_timer);

   // Параллельный запуск двух разных частот полифония.

   // Голос 1: 440 Гц (нота Ля)
   play_voice(1, 440, 180); // Играть 10 секунд, 18 тиков = 1 сек

   // Голос 2: 554 Гц, нота До-диез
   play_voice(2, 554, 180);

   // Ожидание нажатия клавиши...
   while (!kbhit())
   {
      // Цикл программы...
   }
   getch();

   // Восстановить системный таймер и выключить звук.
   setvect(8, old_timer);
   outportb(0x61, inportb(0x61) & 0xFC);

   return 0;
}

 Развернуть:
Изображение
Вложения
Polyphon.zip
(20.74 Кб) Скачиваний: 6
Последний раз редактировалось luzga 01 авг 2026, 15:03, всего редактировалось 3 раз(а).
Аватара пользователя
luzga
Мастер Даунгрейда
 
Сообщения: 478
Зарегистрирован: 04 сен 2025, 19:35

Re: Программирование на Си в MS-DOS

Сообщение Prizrak » 01 авг 2026, 15:01

luzga писал(а):Prizrak, я вас понял.
Предлагаю попробовать следующую программу. Запускает воспроизведения звука через PC Speaker.
Два голоса, играют разные ноты одновременно за счет перехвата системного таймера irq 0, int 8.
 Развернуть: Псевдополифония
Код: Выделить всё
// Программа параллельного запуска двух разных частот полифонии.
// Голос 1: 440 Гц (нота Ля)
// Голос 2: 554 Гц, нота До-диез
// Звук воспроизведения через PC Speaker (Динамик ПК).
//
// Двухканальная псевдополифония. Два логических процесса или
// голоса, играющих разные ноты одновременно за счет перехвата
// системного таймера irq 0, int 8.

#include <dos.h>
#include <conio.h>
#include <stdio.h>

// Старый вектор прерывания таймера.
void interrupt (*old_timer)(...);

// Структура для процесса, голоса воспроизведения.
typedef struct {
unsigned long duration;   // Длительность в тиках таймера.
unsigned frequency;      // Частота звука Гц.
unsigned long counter;   // Текущий счетчик смены фазы.
int active;            // Флаг активности канала.
} Voice;

Voice voice1 = {0, 0, 0, 0};
Voice voice2 = {0, 0, 0, 0};

// Текущая, выводимая частота на динамик.
unsigned current_freq;
int toggle_channel;

void interrupt new_timer(...)
{
   // Функция, устанавливает новое прерывание таймера,
   // вызывается 18.2 раза в секунду или чаще при перенастройке.

   // Вызвать оригинальный, системный обработчик DOS,
   // чтобы часы не отставали.
   old_timer();

   // Чередование каналов.
   if (voice1.active && voice2.active) {
      toggle_channel = !toggle_channel;
      current_freq = toggle_channel ? voice1.frequency : voice2.frequency;
   }
   else if (voice1.active)
      current_freq = voice1.frequency;
   else if (voice2.active)
      current_freq = voice2.frequency;
   else
      current_freq = 0;

   // Управление динамиком.
   if (current_freq > 0)
   {
      unsigned div = 1193180L / current_freq;
      outportb(0x43, 0xB6); // Канал 2, режим 3, меандр.
      outportb(0x42, div & 0xFF);
      outportb(0x42, div >> 8);

      // Включить динамик, биты 0 и 1 порта 0x61
      outportb(0x61, inportb(0x61) | 3);
   }
   else
   {
      // Выключить динамик.
      outportb(0x61, inportb(0x61) & 0xFC);
   }

   // Уменьшить счетчики длительности.
   if (voice1.active)
   {
      if (--voice1.duration == 0)
         voice1.active = 0;
   }
   if (voice2.active)
   {
      if (--voice2.duration == 0)
         voice2.active = 0;
   }
}

void play_voice(int channel, unsigned freq, unsigned long dur)
{
   // Функция запуска ноты
   // в первом или втором процессе...

   disable(); // Запретить прерывания при изменении общей структуры.
   if (1 == channel)
   {
      voice1.frequency = freq;
      voice1.duration = dur;
      voice1.active = 1;
   }
   else
   {
      voice2.frequency = freq;
      voice2.duration = dur;
      voice2.active = 1;
   }
   enable();
}

int main()
{
   clrscr();
   printf("PC Speaker Ї®«Ёд®­Ёп. „«п ўл室 , ­ ¦¬ЁвҐ «оЎго Є« ўЁиг...\n");

   // Сохранить старый и установить новый
   // обработчик прерывания таймера.
   old_timer = getvect(8);
   setvect(8, new_timer);

   // Параллельный запуск двух разных частот полифония.

   // Голос 1: 440 Гц (нота Ля)
   play_voice(1, 440, 180); // Играть 10 секунд, 18 тиков = 1 сек

   // Голос 2: 554 Гц, нота До-диез
   play_voice(2, 554, 180);

   // Ожидание нажатия клавиши...
   while (!kbhit())
   {
      // Цикл программы...
   }
   getch();

   // Восстановить системный таймер и выключить звук.
   setvect(8, old_timer);
   outportb(0x61, inportb(0x61) & 0xFC);

   return 0;
}

 Развернуть:
Изображение

Спасибо! Вечером буду изучать - пока не до ноутбука... :oops:
Аватара пользователя
Prizrak
Мастер Даунгрейда
 
Сообщения: 275
Зарегистрирован: 09 окт 2024, 19:20
Откуда: Минск
Железо: Ноутбук HP, планшетник Android

Re: Программирование на Си в MS-DOS

Сообщение luzga » 01 авг 2026, 16:09

Не знаю, полезно ли это будет, но я добавил загрузку параметров из файлов. Во всяком случае на этом примере, сможете модифицировать под свои нужды. Просто не особенно представляю как вы будете работать.

Эта версия загружает три параметра из двух файлов Par1.txt и Par2.txt
Нужно, чтобы они находились в папке программы и содержали такой текст
 Развернуть: Par1.txt
Код: Выделить всё
1 440 180

 Развернуть: Par2.txt
Код: Выделить всё
2 554 180

 Развернуть: Main.cpp
Код: Выделить всё
// Main.cpp
//
// Программа реализует двухканальный псевдополифонический бипер, два
// логических процесса или голоса, играющих разные ноты одновременно
// за счет перехвата системного таймера Irq 0, Int 8.
// Звук воспроизведения через динамик ПК (PC Speaker).
//
// Программа получает параметры из двух файлов par1.txt и par2.txt
// формат записи: 1 440 180

#include <dos.h>
#include <conio.h>
#include <stdio.h>

#define DEFAULT_FILE_NAME_01 "par1.txt"
#define DEFAULT_FILE_NAME_02 "par2.txt"

// Старый вектор прерывания таймера.
void interrupt (*old_timer)(...);

// Структура для процесса, голоса воспроизведения.
typedef struct {
unsigned long duration;   // Длительность в тиках таймера.
unsigned frequency;      // Частота звука Гц.
unsigned long counter;   // Текущий счетчик смены фазы.
int active;         // Флаг активности канала.
} Voice;

Voice voice1 = {0, 0, 0, 0};
Voice voice2 = {0, 0, 0, 0};

// Текущая, выводимая частота на динамик.
unsigned current_freq;
int toggle_channel;

void interrupt new_timer(...)
{
   // Функция, устанавливает новое прерывание таймера,
   // вызывается 18.2 раза в секунду или чаще при перенастройке.

   // Вызвать оригинальный, системный обработчик DOS,
   // чтобы часы не отставали.
   old_timer();

   // Чередование каналов.
   if (voice1.active && voice2.active) {
      toggle_channel = !toggle_channel;
      current_freq = toggle_channel ? voice1.frequency : voice2.frequency;
   }
   else if (voice1.active)
      current_freq = voice1.frequency;
   else if (voice2.active)
      current_freq = voice2.frequency;
   else
      current_freq = 0;

   // Управление динамиком.
   if (current_freq > 0)
   {
      unsigned div = 1193180L / current_freq;
      outportb(0x43, 0xB6); // Канал 2, режим 3, меандр.
      outportb(0x42, div & 0xFF);
      outportb(0x42, div >> 8);

      // Включить динамик, биты 0 и 1 порта 0x61
      outportb(0x61, inportb(0x61) | 3);
   }
   else
   {
      // Выключить динамик.
      outportb(0x61, inportb(0x61) & 0xFC);
   }

   // Уменьшить счетчики длительности.
   if (voice1.active)
   {
      if (--voice1.duration == 0)
         voice1.active = 0;
   }
   if (voice2.active)
   {
      if (--voice2.duration == 0)
         voice2.active = 0;
   }
}

void play_voice(int channel, unsigned freq, unsigned long dur)
{
   // Функция запуска ноты
   // в первом или втором процессе...

   disable(); // Запретить прерывания при изменении общей структуры.
   if (1 == channel)
   {
      voice1.frequency = freq;
      voice1.duration = dur;
      voice1.active = 1;
   }
   else
   {
      voice2.frequency = freq;
      voice2.duration = dur;
      voice2.active = 1;
   }
   enable();
}

int main()
{
   // Получить параметры воспроизведения из файлов.
   
   const char* svFilename1 = DEFAULT_FILE_NAME_01;
   const char* svFilename2 = DEFAULT_FILE_NAME_02;

   // Открыть первый текстовый файл для чтения.
   FILE* f1 = fopen(svFilename1, "r");
   if (!f1) {
      printf("Could not opening %s\n", svFilename1);
      return 1;
   }

   // Открыть второй текстовый файл для чтения.
   FILE* f2 = fopen(svFilename2, "r");
   if (!f2) {
      printf("Could not opening %s\n", svFilename2);
      fclose(f1);
      return 1;
   }

   // Прочитать три параметра из первого файла
   // 1 440 180
   int a1, b1, c1;
   if (3 != fscanf(f1, "%d %d %d", &a1, &b1, &c1)) {
      printf("Error reading data from %s\n", svFilename1);      
      fclose(f1);
      fclose(f2);
      return 1;
   }

   // Прочитать три параметра из второго файла
   // 2 554 180
   int a2, b2, c2;
   if (3 != fscanf(f2, "%d %d %d", &a2, &b2, &c2)) {
      printf("Error reading data from %s\n", svFilename2);
      fclose(f1);
      fclose(f2);
      return 1;
   }

   // Закрыть файлы после чтения.
   fclose(f1);
   fclose(f2);

   clrscr();
   printf("PC Speaker Ї®«Ёд®­Ёп. „«п ўл室 , ­ ¦¬ЁвҐ «оЎго Є« ўЁиг...\n");

   // Сохранить старый и установить новый
   // обработчик прерывания таймера.
   old_timer = getvect(8);
   setvect(8, new_timer);

   // Параллельный запуск двух разных частот полифония.

   // Голос 1
   play_voice(a1, b1, c1);
   //play_voice(1, 440, 180); // 440 Гц, нота Ля, Играть 10 секунд, 18 тиков = 1 сек.
   
   // Голос 2
   play_voice(a2, b2, c2);
   //play_voice(2, 554, 180); // 554 Гц, нота До-диез

   // Ожидание нажатия клавиши...
   while (!kbhit())
   {
      // Цикл программы...
   }
   getch();

   // Восстановить системный таймер и выключить звук.
   setvect(8, old_timer);
   outportb(0x61, inportb(0x61) & 0xFC);

   return 0;
}
Вложения
Polyphon.zip
(24.47 Кб) Скачиваний: 4
Последний раз редактировалось luzga 02 авг 2026, 06:04, всего редактировалось 3 раз(а).
Аватара пользователя
luzga
Мастер Даунгрейда
 
Сообщения: 478
Зарегистрирован: 04 сен 2025, 19:35

След.

Вернуться в Программирование

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1