Создание приложения, обеспечивающего генерацию звука с помощью системного таймера

АННОТАЦИЯ
Данная курсовая работапредставляет собой приложение, обеспечивающее генерацию звука с помощьюсистемного таймера.
Так как в настоящее времявоспроизведение звука происходит посредством звуковых плат, обычный динамик PC практически никем не используется,поэтому главное его применение – звуковое сопровождение при выдаче сообщений обошибках.

1. ИССЛЕДОВАТЕЛЬСКАЯ ЧАСТЬ
 
1.1 Исследование предметной области ипостановка задачи
Целью данной курсовойработы является разработка приложения, которое может генерировать звук,используя системный таймер.
Для достижения даннойцели необходимо реализовать ряд задач, а именно:
–    изучить принципработы системного таймера
–    разработатьалгоритмы для перехвата и обработки прерываний системного таймера
–    создать процедурудля извлечения очередного звука
–    создать процедурудля обработки символов, введенных с клавиатуры
 
1.2 Общие сведения о языке
 
Языкассемблера — этосимволическое представление машинного языка. Все процессы в машине на самомнизком, аппаратном уровне приводятся в действие только командами (инструкциями)машинного языка. Отсюда понятно, что, несмотря на общее название, языкассемблера для каждого типа компьютера свой. Это касается и внешнего видапрограмм, написанных на ассемблере, и идей, отражением которых этот языкявляется.
Язык ассемблера был создан для облегчения написания программ нанизком уровне. Вместо машинных команд программист использует мнемоники, которыепредставляют собой символическое представление машинной команды (или несколькихкоманд), что облегчает чтение текста программы. Так как одна мнемоника притрансляции преобразовывается в минимальное количество команд, то программы,написанные на ассемблере, выполняются с максимально возможной скоростью изанимают минимальный объём памяти. Именно поэтому программы на ассемблере (илиассемблерные вставки) используются там, где быстродействие является наиболеекритичным фактором (обработка компьютерной графики, ядро операционных систем),или требуется максимально полно использовать возможности операционной системы(вирусы и антивирусы), или там, где эти два качества являются одинаково важными(драйверы различных устройств). Хорошим качеством Ассемблера является то, чтоон позволяет управлять действиями процессора поэтапно (по операциям) и смаксимальной эффективностью. Ассемблер предоставляет программисту полнуюсвободу действий при разработке программы, что одновременно является и егодостоинством, и недостатком, так как требует от разработчика знания системыкоманд данного компьютера и его операционной системы. Данный языкпозволяет программисту непосредственно работать со всем аппаратным обеспечением,что особенно важно при программировании устройств — ввода-вывода, где требуетсяконтроль над отдельными разрядами регистров устройства. Ассемблер предоставляетвозможность создания компактных и быстродействующих программ, оптимизацииработы с аппаратными средствами. Синтаксис инструкций процессора предоставляетпрограммисту широкий выбор типов данных: целые числа, строки знаков,упакованные десятичные числа, числа с плавающей точкой, структуры и записи. В языкеимеется возможность подключения фрагментов исходного текста из других файлов.Ассемблер имеет набор макро-директив, использование которых позволяетотносительно просто повторять общие блоки предложений несколько раз илизаменять макро-имена в исходном тексте целыми последовательностями предложений.
 
1.3 Элементы языка
Для написания курсовойработы были использованы следующие средства языка:
1.        Команды пересылкиданных
–    Команда MOV приемник, источник
Назначение: пересылкаданных между регистрами или регистрами и памятью.
–    Команда XCHGоперанд_1, операнд_2
Назначение: обмен двухзначений между регистрами или между регистрами и памятью. Команду xchgможно использовать для выполнения операции обмена двух операндов с цельюизменения порядка следования байт, слов, двойных слов или их временногосохранения в регистре или памяти.
–    Команда LEA приемник, источник
Назначение: получениеэффективного адреса (смещения) источника. Алгоритм работы команды зависит отдействующего режима адресации (use16 или use32):
если use16, то в регистрприемник загружается 16-битное значение смещения операнда источник;
если use32, то в регистрприемник загружается 32-битное значение смещения операнда источник.
–    Команда IN аккумулятор, ном_порта
Назначение: ввод значенияиз порта ввода-вывода. Передает байт, слово, двойное слово из портаввода-вывода в один из регистров al/ax/eax
–    Команда OUT ном_порта, аккумулятор
Назначение: выводзначения в порт ввода-вывода. Передать байт, слово, двойное слово из регистраal/ax/eax в порт, номер которого определяется первым операндом.
–    КомандаPUSHA
Назначение: размещение встеке регистров общего назначения в следующей последовательности: ax, cx, dx,bx, sp, bp, si, di. Уменьшает значение указателя стека esp/sp на 32/16 (взависимости от значения атрибута размера адреса — use16 или use32), включиет встек последовательно значения регистров общего назначения ax, cx, dx, bx, sp,bp, si, di. Содержимое di при этом будет на вершине стека. В стек помещаетсясодержимое sp по состоянию до выполнения команды.
–    Команда POPA
Назначение: извлечение изстека регистров общего назначения di, si, bp, sp, bx, dx, cx, ax. Извлекает изстека последовательно значения и загрузжает ими регистры общего назначения di,si, bp, sp, bx, dx, cx, ax. Содержимое di восстанавливается первым. Содержимоеsp извлекается, но не восстанавливается. Увеличивает значение указателя стекаesp/sp на 16.
2.        Арифметическиекоманды
–    Команда INC операнд
Назначение: увеличениезначения операнда в памяти или регистре на единицу.
–    Команда DEC операнд
Назначение: уменьшениезначения операнда в памяти или регистре на единицу.
3.        Командылогической обработки данных
–    Команда AND приемник, источник
Назначение: операциялогического умножения для операндов приемник и источник размерностью байт,слово или двойное слово. Выполняет операцию логического умножения надоперандами источник и приемник: каждый бит результата равен 1, еслисоответствующие биты операндов равны 1, в остальных случаях бит результатаравен 0.Результат операции записывается в приемник. Устанавливаются флаги.
–    Команда OR приемник, маска
Назначение: операциялогического ИЛИ над битами операнда назначения, используя в качестве маскивторой операнд — маска. При этом бит результата равен 0, если соответствующиебиты операндов маска и назначения равны 0, в противном случае бит равен 1.Результат операции записывается в источник (маска неизменна). Устанавливаютсяфлаги.
–    Команда XOR приемник, источник
Назначение: операциялогического исключающего ИЛИ над двумя операндами размерностью байт, слово илидвойное слово. Бит результата равен 1, если значения соответствующих битовоперандов различны, в остальных случаях бит результата равен 0. Результатоперации записывается в приемник. Устанавливаются флаги.
–    Команда TEST приемник, источник
Назначение: операциялогического сравнения операндов приемник и источник размерностью байт, словоили двойное слово, при этом бит результата равен 1, если соответствующие битыоперандов равны 1, в остальных случаях бит результата равен 0. Устанавливаютсяфлаги.
–    Команда SHL операнд, количество_сдвигов
Назначение: логическийсдвиг операнда влево. Происходит сдвиг всех битов операнда влево на одинразряд, при этом выдвигаемый слева бит становится значением флага переноса cf,одновременно слева в операнд вдвигается нулевой бит. Указанные выше двадействия повторяются количество раз, равное значению второго операнда.
4.        Команды передачиуправления
–    Команда CMP операнд1, операнд2
Назначение: сравнениедвух операндов. Выполняет вычитание (операнд1-операнд2). В зависимости отрезультата устанавливает флаги, операнд1 и операнд2 не изменяются
–    Команда JMP метка
Назначение: используетсяв программе для организации безусловного перехода как внутри текущего сегментакоманд, так и за его пределы. При определенных условиях в защищенном режимеработы команда jmp может использоваться для переключения задач.
5.        Команда CALL цель
Назначение: передачауправления близкой или дальней процедуре с запоминанием в стеке адреса точкивозврата и переключение задач.
Командаcall передает управление внешнейпроцедуре, предварительно сохранив в стеке информацию для последующего возвратав вызывающую процедуру при помощи команды ret. Команда call имеетразличную форму записи в зависимости от типа вызываемой процедуры (дальняя илиближняя). Команда ret, которойзавершается вызываемая процедура, должна иметь тот же тип (дальний илиближний), что и вызывающая процедуру команда call. Адрес вызываемой процедуры может быть задан непосредственнов команде call, в памяти или в регистре.
6.        Команда RET
Назначение:возврат управления из процедуры вызывающей программе.
Командаret возвращает управление из вызваннойпроцедуры команде, следующей за командой call. Если возврат осуществляется из ближней процедуры,возврат является внутрисегментным (содержимое регистра CS остается неизменным).При возврате из дальней процедуры возврат является межсегментным (из стекавосстанавливаются значения CS и IP). Если в команде задано необязательное значение,команда ret добавляет это значение к указателюстека SP. Это позволяет пропускать параметры, передаваемые через стек передкомандой call.
7.        Команда IRET
Назначение:используется в той точке программы обработки прерывания, откуда необходимовернуть управление прерванной программе. Команду iret необходимо применять длявосстановления сохраненных командой int регистров флагов, указателя команд исегментного регистра кода. Число этих команд в программе обработки прерываниядолжно соответствовать количеству точек выхода из нее.
8.        Командапрерываний INT число
Назначение: Вызовпрерывания
INT помещает в стексодержимое регистров EFLAGS, CS и EIP, после чего передает управлениепрограмме, называемой «обработчик прерывания» с указанным в качестве операнданомером (число от 0 до 0FFh), аналогично команде call. В реальном режиме адреса обработчиков прерыванийсчитываются из таблицы, начинающейся в памяти по адресу 0000h:0000h. Адрескаждого обработчика занимает 4 байта, так что, например, адрес обработчика прерывания10h находится в памяти по адресу 0000h:0040h. В защищенном режиме адресаобработчиков прерываний находятся в таблице IDT и обычно недоступны для прямогочтения или записи, так что для установки собственного обработчика программадолжна обращаться к операционной системе. В DOS вызовы прерываний используютсядля выполнения большинства системных функций – работы с файлами,вводом/выводом и т.д.
9.        Процедуры
Синтаксис описания процедуры:
имя_процедуры PROC[модификатор языка] [расстояние]

[имя_процедуры] ENDP
Процедура, частоназываемая также подпрограммой, — это основная функциональная единицадекомпозиции (разделения на несколько частей) некоторой задачи. Процедурапредставляет собой группу команд для решения конкретной подзадачи и обладаетсредствами получения управления из точки вызова задачи более высокого уровня ивозврата управления в эту точку. В простейшем случае программа может состоятьиз одной процедуры. Другими словами, процедуру можно определить как правильнымобразом оформленную совокупность команд, которая, будучи однократно описана,при необходимости может быть вызвана в любом месте программы.
Средибольшого количества операндов директивы PROC следует особо выделить [расстояние].Этот атрибут может принимать значения near или far и характеризует возможностьобращения к процедуре из другого сегмента кода. По умолчанию атрибут[расстояние] принимает значение near.
Процедураможет размещаться в любом месте программы, но так, чтобы на нее случайнымобразом не попало управление. Если процедуру просто вставить в общий потоккоманд, то микропроцессор будет воспринимать команды процедуры как часть этогопотока и соответственно будет осуществлять выполнение команд процедуры.
10.     Системный таймер
Таймеру соответствуютчетыре порта ввода/вывода со следующими адресами:
–    40h — канал 0;
–    41h — канал 1;
–    42h — канал 2;
–    43h — управляющийрегистр.
Одно из наиболеераспространенных применений таймера — генерация звуковых сигналов ивоспроизведение музыки. Таймер позволяет воспроизводить музыку в фоновомрежиме, т.е. во время работы программы может звучать музыка.
Как мы уже говорили,канал 2 микросхемы 8254 связан с громкоговорителем компьютера. Однакогромкоговоритель не просто соединен с выходом OUT канала 2. Порт вывода 61hтакже используется для управления громкоговорителем. Младший бит порта 61hподключен ко входу GATE канала 2 таймера. Этот бит при установке в 1 разрешаетработу канала, т.е. генерацию импульсов для громкоговорителя.
Дополнительно дляуправления громкоговорителем используется бит 1 порта 61h. Если этот битустановлен в 1, импульсы от канала 2 таймера смогут проходить нагромкоговоритель.
Таким образом, длявключения звука надо выполнить следующие действия:
–    запрограммироватьканал 2 таймера на нужную частоту (т.е. загрузить регистр счетчика каналанужным значением);
–    для включениязвука установить в 1 два младших бита порта 61h.
Так как остальные 6 битовпорта 61h используются для других целей, установка младших битов должнавыполняться таким образом, чтобы значения остальных битов не были изменены. Дляэтого вначале надо считать байт из порта 61h в рабочую ячейку памяти,установить там нужные биты, затем вывести новое значение байта в порт 61h.
Очевидно, что длявыключения звука надо сбросить два младших бита порта 61h в 0 (при этом нельзяизменять значение остальных битов этого порта).
Мелодия (одноголосая),как известно, состоит из нот, разделенных или не разделенных паузами. Припроигрывании мелодии необходимо для каждой ноты программировать соответствующимобразом канал 2 таймера и включать громкоговоритель (с помощью порта 61h) наопределенное время, равное длительности ноты. Затем программа должна выключитьдинамик и выдержать паузу перед проигрыванием следующей ноты, если такая паузатребуется.
Основная идея заключаетсяв использовании прерывания 1Ch, которое вырабатывается таймером с частотойпримерно 18,2 Гц. Пользовательский обработчик этого прерывания осуществляетконтроль за выборкой нот из массива, содержащего мелодию, и программированиемикросхемы 8254. Если подготовить таблицы частот и длительностей, то можнопроигрывать простейшие мелодии.
Для определения значения,которое должно быть записано в регистр счетчика канала 2 таймера, надоразделить 1193180 на требуемую частоту в герцах.
В таблице ниже приведенычастоты нот для второй октавы. При повышении (понижении) тона на октаву частотасоответствующей ноты умножается (делится) на два.

Таблица 1 — Частоты нот
Нота
Частота, Гц До 261,7 До-диез 277,2 Ре 293,7 Ре-диез 311,1 Ми 329,6 Фа 349,2 Фа-диез 370 Соль 392 Соль-диез 415,3 Ля 440 Ля-диез 466,2 Си 493,9

2. КОНСТРУКТОРСКАЯ ЧАСТЬ
 
2.1 Общиесведения
Данная программа написана на ассемблере языке программированиянизкого уровня, создана с использованием программных средств пакета Tasm и редактора AsmEdit. Исполняемыйфайл программы находится в формате.exe и называется kur.exe.
/> 
2.2 Функциональное назначение
Даннаяпрограмма позволяет пользователю выбрать одну из двух представленных мелодийдля генерации и воспроизведения.
 
2.3 Описание логической структурыпрограммы
 
2.3.1 Алгоритм работы программы
— Выводна экран строки
— Сохранениестарого вектора прерывания
— Установканового вектора прерывания
— Опросклавиатуры
— Есливыбран номер мелодии, то поместить массив в аккумулятор
— Иначе:восстановление обработчика прерывания и выход
 
2.3.2 Используемые методы
В начале программыпроисходит инициализация сегментного регистра CS. Все данные, которые описаны в программе, размещаются врегистре команд. После запуска программы на экран выводится сообщение.Происходит сохранение старого вектора прерывания и инициализации нового. Взависимости от выбора пользователя, после опроса клавиатуры, программапродолжает работу и передает текущую ноту в регистр-аккумулятор, либопроисходит восстановление прерывания и выход их программы. Выход из программыпроисходит при нажатии кнопки “q”. Основнаяпроцедура программы — Start proc (см.Приложение 1, стр. 22).
Нижеописаны подпрограммы, которые вызывают в главной:
— new_int1cproc near – новый обработчик прерываний (см.Приложение 1, стр.23).
Происходитсохранение всех регистров, вызывается процедура генерации звука, восстановлениевсех регистров и происходит возврат из программы обработки прерывания.
— kbinproc near — проверка введенного символа для дальнейшей передачи управления(см.Приложение 1, стр.24).
Происходитвызов клавиатурного прерывания для считывания символа и выход из процедуры.
— muzproc near – процедура извлечения очередного звука (см. Приложение 1,стр.23).
Первымделом осуществляется проверка, установлена ли переменная iniflag (онаиспользуется как флаг). Если нет, что считывается состоянии системного порта РВППИ, в 0 и 1 бит заносятся 0 и записывается обратно в порт. Таким образомпроисходит запрет звучания.
Еслифлаг установлен, то считывается текущая нота. Если она равно 255 (то есть этопауза), то происходит запрету звучания и продолжение считывания нот. Впротивном случае проверяется, если нота равно 0 (то есть конец массива нот), топроисходит переход на начало выполнения программы и происходит выход, если флагне возведен.
Еслитекущая нота не равно 255 или 0, то происходит считывание частоты ноты, младшийи старший байты которой заносятся во второй канал таймера. Далее происходиразрешение звучания, то есть считывается значение системного порта РВ ППИ, в 0и 1 бат заносятся единицы и отправляется обратного в порт. И происходитнормальный выход из процедуры.
 
2.3.3 Вызов и загрузка
Вызов программы осуществляется путём запуска файла «kur.exe». Если файл не существует,его необходимо скомпилировать из файла исходного текста программы под названием«kur.asm».
 
2.3.4 Входные данные
Входными даннымипрограммы является ввод пользователем пункта меню.
 
2.3.5 Выходные данные
Выходными даннымипрограммы является звуковой сигнал динамика. Так же на экран выводится простоепользовательское меню.

3.ТЕХНОЛОГИЧЕСКАЯ ЧАСТЬ
 
3.1 Общие сведения
Для создания курсовойработы использовалось следующее программное обеспечение:
·         Компилятор TASM
·         Компоновщик Tlink.exe
·         Отладчик TD.EXE
·         Текстовыйредактор – ASMEditor
·         MSOffice Word 2003
·         MSOffice Visio 2003
 
3.2 Руководство системного программиста
 
3.2.1 Системные требования
Минимальные системныетребования:
–    Процессор 80286 ивыше
–    Оперативнаяпамять – 1 Мб
–    Свободного местана жестком диске 1 Мб
–    Операционнаясистема DOS 3.3 и выше / Windows 9x/ME
–    Клавиатура
–    Мышь
 
3.2.2 Структура программы
Программа представляет собой один исходный файл для выполнения иназывается Kur.exe. Она неимеет никаких связей с другими программами и работает автономно.

3.2.3Тестирование программы
Послезапуска произойдет размещение программы в памяти. При наборе на клавиатуре 1произойдет загрузка в регистр-аккумулятор мелодии «Чижик-пыжик», которая будетсгенерирована и воспроизведена через системный динамик. При наборе цифры 2произойдет загрузка мелодии «Подмосковные вечера», которая будетвоспроизводиться аналогично первому случаю. Если будет набрано «q», то произойдет завершение работы программы и выгрузка еёиз памяти.
 
3.2.4 Выходные и выходные данные
Входнымиданными является номер выбранного пункта меню.
Выходные данные – этосгенерированная мелодия в соответствии с выбранным пунктом.
 
3.3 Руководство оператора
 
3.3.1 Назначение программы
Данная программапредназначена для генерации звука с использованием системного таймерапосредством системного динамика.
 
3.3.2 Выполнение программы
1.  Для запуска программы необходимо запустить приложение Kur.exe
2.  Выбрать любой из предложенных пунктов меню.
3.  Для генерации мелодии «Чижик-Пыжик» выберите пункт 1
4.  Для генерации мелодии «Подмосковные вечера» выберите пункт 2
5.   Для выхода из программы выход из программы выберите пункт q
 
3.3.3 Сообщения оператору
При загрузке программы выводится простое пользовательское меню:
Enter the point of menu:
1- CHIZHIK-PYZHIK
2 — PODMOCKOVNYE VECHERA
q – Qiute
Если пользователь введет пункт меню, который не предусмотренпрограммой, то на экран будет выведено сообщение.

ЗАКЛЮЧЕНИЕ
В ходе выполнениякурсовой работы было создано приложение, которое способно генерировать мелодии«Чижик-Пыжик» и «Подмосковные вечера».
Для реализациипоставленной цели были реализованы следующие задачи:
–    Изучены принципыработы системного таймера
–    Разработаныалгоритмы для перехвата и обработки прерываний системного таймера
–    Создана процедурадля извлечения очередного звука
–    Создана процедурадля обработки символов, введенных с клавиатуры

СПИСОК ЛИТЕРАТУРЫ
1.     Абель П. Язык Ассемблерадля IBM PC и его программирование — М.: Высшая школа,1992. – 252с.
2.     С.В. ЗубковАссемблер для DOS, Windows и Unix – М.: ДМК Пресс, 1999. – 630 с.
3.     И. Юров Assembler– СПб.: Питер, 2001. – 624 с.

ПРИЛОЖЕНИЕ 1
Листинг программы
Assume CS:Code
Code SEGMENT
286
Start proc; Основнаяпроцедура
mov ax,cs
mov ds,ax; DS = CS
iniflag db 0; Флагзвучания
old_int1c_off dw 0;Смещение старого вектора
old_int1c_seg dw 0;Сегмент старого вектора
tek_mel dw?; Адрестекущей ноты выбранной мелодии
mov ax,351ch
int 21h
movcs:old_int1c_off,bx
movcs:old_int1c_seg,es
leadx,new_int1c
mov ax,251ch
int 21h; DS:DX – адресновой программы обр.
mov ah,09h
lea dx,menu
int 21h
beg1:
call kbin; Опрос клавиатуры
cmp al,’1′
jnz beg2; Нет
mov byte ptriniflag,1; Взведение флага звуч.
lea ax,mel1
mov tek_mel,ax
jmp beg1; Переход наначало цикла
beg2:
cmp al,’2′
jnz beg3
mov byte ptriniflag,1
lea ax,mel2
mov tek_mel,ax
jmp beg1
beg3:
cmp al,’q’
jnz beg4
jmp beg5
beg4:
mov ah,09h
lea dx,er
int 21h
jmp beg1
beg5:
Восстановление староговектора 1с и выход
movdx,old_int1c_off
movax,old_int1c_seg
mov ds,ax; DS:DX – адресустанавл. вектора
mov ax,251ch
int 21h
movax,4c00h
int21h
start endp
Новый обработчикпрерывания 1ch
new_int1c procfar
pusha
call muz; Вызов процедура извлечения звука
popa
iret
new_int1c endp
Процедура извлеченияочередного звука
tek_mel – адрес текущейноты выбранной мелодии
muz proc near
test byte ptrcs:iniflag,0ffh; Проверка флага
jnz muz1
muze:
in al,61h; Чтениесостояния системного порта В
and al,0fch; Запрещениезвучания (биты 0 и 1)
out 61h,al; Запись всистемный порт В
jmp ex; Выход, если флагне взведен
muz1:
mov si,cs:tek_mel; Адрестекущей ноты
mov bl,cs:[si]; Текущаянота
cmp bl,255; Пауза?
jnz muz2
Выключение звука
in al,61h
and al,0fch
out 61h,al
inc cs:tek_mel; Переход кадресу след. ноты
jmp ex
muz2:
or bl,bl; = 0?
jnz muz3
jmp muze
muz3:
xor bh,bh
mov ax,cs:noty[bx]
Программирование делителячастоты 2 канала
inc cs:tek_mel; Переход кадресу след. ноты
out 42h,al; Мл.байтчастоты. канал 2 таймера
xchg al,ah; AH. AL
out 42h,al; Ст. байтчастоты. канал 2 таймера
Разрешение звучания
in al,61h
or al,3; Разрешениезвучания (биты 0 и 1)
out 61h,al; Запись всистемный порт В
ex:
ret
muz endp
kbin proc near; Ввод склавиатуры и проверка на выбор игры
mov ah,0
int 16h
ret
kbin endp
Мелодия «Чижик Пыжик»
mel1 db17,17,255,13,13,255,17,17,255,13,13,255,18,18,255
db17,17,255,15,15,15,15,255,255
db 8,8,255,8,8,255,8,8,255,10,255,12,255
db13,13,255,13,13,255,13,13,13,13
db 0
Мелодия«Подмосковные вечера»
mel2 db1,1,1,4,4,4,8,8,8,4,4,4,6,6,6,6,6,6,4,4,4,3,3,3
db8,8,8,8,8,8,6,6,6,6,6,6,1,1,1,1,1,1,1,1,1,1,1,1
db 0
menu db 10dup(0ah), 30 dup(20h), ‘Enter the point of menu:’
db 0dh,0ah,30dup(20h),’1 — CHIZHIK-PYZHIK’.0dh,0ah,30 dup(20h),’2 — PODMOCKOVNYE VECHERA’.0dh,0ah,30dup(20h), ‘q — Quit’,5 dup(0ah), “$ ”
er db’Incorrect input! Try again!’,0dh,0ah,”$ ”
Коэффициенты делениядля нот
noty dw0eeeh,0e18h,0d49h,0c8eh,0bdfh,0b2fh,0abeh
dw9f7h,968h,8e0h,861h,7e8h,777h,70ch,6a5h,647h
dw5edh,597h,547h,4fbh,4b4h,470h,430h,3f4h
dw3bbh,386h,352h,323h,2f6h,2cbh,2a3h,27dh,25ah,238h,218h,1fah
dw1ddh,1c3h,1a9h,192h,17bh,166h,152h,13fh,12dh,11ch,10ch,0fdh
dw 0
code ends
END

ПРИЛОЖЕНИЕ 2
/>
Рис. 1- Пользовательское меню
/>
Рис. 2- Некорректный ввод