Допомога у написанні освітніх робіт...
Допоможемо швидко та з гарантією якості!

Генерування звукових сигналів різної частоти за допомогою клавіатури

КурсоваДопомога в написанніДізнатися вартістьмоєї роботи

Для обробки і видачі звуків через динамік буде використовуватися програмування мікросхеми таймера. Всі ІBM PC використовують мікросхему таймера 8253 (чи 8254) для узгодження імпульсів від мікросхеми системного годинника. Число циклів системного годинника перетвориться в один імпульс, а послідовність цих імпульсів підраховується для визначення часу, чи вони можуть бути послані на гучномовець… Читати ще >

Генерування звукових сигналів різної частоти за допомогою клавіатури (реферат, курсова, диплом, контрольна)

Курсова робота

з дисципліни «Системне програмування»

на тему:

«Генерування звукових сигналів різної частоти за допомогою клавіатури «

ЗМІСТ Вступ

Розділ 1. Аналіз технічного завдання та методів його вирішення Розділ 2. Опис методики та алгоритму вирішення задачі

Розділ 3. Опис програми та аналіз отриманих результатів

Висновок

Список використаних джерел Додаток А

Додаток Б

ВСТУП Сучасне комп’ютерне програмне забезпечення перетворило персональні ПК у потужні обчислювальні машини, які здатні виконувати найрізноманітніші завдання. На даний момент існує безліч програм, які здатні задовольнити потреби користувачів у різних галузях науки та повсякденному житті: фізика, математика, графіка, економіка, бізнес тощо. Також у свою чергу розвивається програмне забезпечення, призначене для створення та написання музики.

На даний момент музичні програми здатні замінити навіть живі інструменти.

Завдання курсової роботи полягає в тому, щоб скласти програму яка здатна відтворювати системним динаміком звуки різної частоти. Основою цього програмування є програмування мікросхеми таймера 8253 або 8255.

Для розв’язання поставленої задачі вибрана мова програмування Асемблер, оскільки вона має досить потужний набір інструментів для того, щоб створювати не тільки звук, але й змінювати його надаючи йому певних відтінків і тонів.

Асемблерні програми можуть бути дуже ефективними. На Асемблері можна написати програму більш компактну і швидкодіючу ніж написану на мові високого рівня. Це дійсно так для невеликих або середніх програм. По мірі зростання розмірів, програми втрачають частину своїх переваг. Це відбувається через необхідність в Асемблерній програмі уваги до дрібниць. Мова Асемблер потребує від програміста планування кожної дії. В невеликих програмах це дозволяє оптимізувати роботу програми з апаратними засобами. У великих програмах величезна кількість деталей може перешкодити эффективно працювати над самою програмою, навіть якщо окремі компоненти програми виявляться дуже непоганими. Безумовно, програмування на мові Асемблера відповідає потребам не кожної програми. Програми на Асемблер дуже точні. Оскільки ця мова дозволяє програмісту безпосередньо працювати з всім апаратним забезпеченням. Поза сумнівом, що при програмуванні пристроїв вводу-виводу, де потрібен контроль над окремими розрядами регістрів пристрою, програмування на мові Асемблер — єдиний правильний вибір. Також програми написані на Асемблері можуть з'єднуватись із програмами, написаними на мовах високого рівня, що дозволяє оптимізувати останні.

РОЗДІЛ 1. АНАЛІЗ ТЕХНІЧНОГО ЗАВДАННЯ ТА МЕТОДІВ ЙОГО ВИРІШЕННЯ Завдання курсової роботи полягає в тому щоб відтворювати звуки заданої частоти. Розглядаючи вхідні дані ми можемо скласти такий їхній перелік: частота звуку, тривалість звуку. Частоту звуку можна в свою чергу розбити ще на приналежність його до певної музичної октави: мала, перша, друга, третя, та ін. Також окремим видом звуку можу бути і шум. Продумуючи програму був обраний шлях який полягає в тому що при натисканні певної клавіші на клавіатурі буде отриманий звук певної частоти, який буде відповідати частоті певної ноти (до, ре, мі, та ін.). Отже основним вихідним результатом має стати програний звук (нота) через системний динамік.

Для обробки і видачі звуків через динамік буде використовуватися програмування мікросхеми таймера. Всі ІBM PC використовують мікросхему таймера 8253 (чи 8254) для узгодження імпульсів від мікросхеми системного годинника. Число циклів системного годинника перетвориться в один імпульс, а послідовність цих імпульсів підраховується для визначення часу, чи вони можуть бути послані на гучномовець комп’ютера для генерації звуку визначеної частоти. Мікросхема 8253 має три ідентичних незалежних канали, кожний з який може програмуватися.

Мікросхема 8253 працює незалежно від процесора. Процесор програмує мікросхему і потім звертається до інших справ. У такий спосіб 8253 діє як годинник реального часу — вона рахує свої імпульси незалежно від того, що відбувається в комп’ютері. Однак, максимальний програмувальний інтервал складає приблизно1/12 секунди. Для підрахунку інтервалів часу в годин та хвилин потрібні якісь інші засоби. Саме з цієї причини імпульси від нульового каналу мікросхеми таймера накопичуються в перемінній, що знаходиться в області даних BІOS.

РОЗДІЛ 2. ОПИС МЕТОДИКИ ТА АЛГОРИТМУ ВИРІШЕННЯ ЗАДАЧІ

Генерація звуку за допомогою адаптера інтерфейсу з периферією 8255 складається у включенні і вимиканні з бажаною частотою біта порту B, що зв’язаний з динаміком (біт 1). Порт B має адреса 61H. Якщо програма переключає значення біта з максимально можливою частотою, то частота занадто висока, щоб бути потрібною. Тому між двома переключеннями треба вставляти порожній цикл. Пам’ятайте, що біт 0 порту B керує воротами каналу 2 мікросхеми таймера, що у свою чергу зв’язаний з динаміком. Тому цей біт повинний бути скинутий, від'єднуючись від каналу таймера.

Ми будемо використовувати той метод, який забезпечує відтворення звуку з іншими діями які відбуваються на РС. Ми використовуємо адрес порту мікросхеми 8255 який знаходиться по адресу 61Н, а для того щоб отримати звук нам потрібно послати число з потрібною частотою в канал 2 який знаходиться по адресу 42Н, а також після цього вимкнути динамік.

В ініціалізаційні частині - області програми, де описані змінні та константи містяться стрічки повідомлень:

slovo1 db 'Space-RESTART', 13,10,'$'

slovo2 db 'Enter-HELP', 13,10,'$'

slovo3 db 'Esc-EXIT', 13,10,'$'

mes db 'Matiyshun Yura$'

string db 'Vuberity trivalisty zvuchannya$'

string1 db 'Zvyk notu :$',

стрічки назв нот (n1 — n15).

not1 db 'DO$'

not2 db 'RE$'

not3 db 'MI$'

not4 db 'FA$'

not5 db 'SOL$'

not6 db 'LA$'

not7 db 'SI$'

not8 db 'DO1 $'

not9 db 'RE1 $'

not10 db 'MI1 $'

not11 db 'FA1 $'

not12 db 'SOL1 $'

not13 db 'LA1 $'

not14 db 'SI1 $'

not15 db 'DO2 $',

тривалості звучання нот:

t1 db '1 $'

t2 db '2 $'

t3 db '3 $'

t4 db '4 $'

t5 db '5 $'

t6 db '6 $',

та текст меню допомоги

help db ' Klavisha — Nota Klavisha — Nota', 13,10

db ' z — Do s — Do (verhnye)', 13,10

db ' x — Re d — Re (verhnye)', 13,10

db ' c — Mi f — Mi (verhnye)', 13,10

db ' v — Fa g — Fa (verhnye)', 13,10

db ' b — Sol h — Sol (verhnye)', 13,10

db ' n — La j — La (verhnye)', 13,10

db ' m — Si k — Si (verhnye)', 13,10,'$'

Також сюди входять змінні NOTE та DELAY.

NOTE dw ('?')

DELAY db ('?')

Ці змінні мають розмір відповідно два та один байт. У змінну NOTE під час виконання програми заноситься частота ноти, яка має програватись, а змінна DELAY призначена для зберігання часу тривалості звучання ноти. Після опису цих даних йде ініціалізація стеку розміром 128 байт:

.stack 128

Нижче розглянемо приклад отримання звуку певної частоти і певної тривалості:

IN AL, 61h — получаємо поточну адресу порту В

OR AL, 11B — дозволяємо таймер і динамік

OUT 61h, AL

Після цього встановлюємо режим для 2-го каналу. Керуюче слово пересилаємо у порт 43Н, який є командним регістром.

MOV AL, 0B6H

OUT 43h, AL

Після цього пересилаємо частоту ноти, яка знаходиться у змінній NOTE, у порт 42Н побайтово, використовуючи регістр AL.

MOV DX, NOTE

MOV AL, DL

OUT 42H, AL

MOV AL, DH

OUT 42H, AL

За допомогою функції 0Н переривання 1АН одержуємо значення лічильника, яке буде використовуватись для затримки звучання ноти. Далі змінну DELAY, у якій міститься час затримки звучання ноти, пересилаємо у регістр CL. Після цього заносимо молодший байт лічильника у регістр ВХ. Сумуємо його із даним часом затримки. Далі виконується переривання INT 1AH і у регістрі DX буде міститися текуче значення лічильника, яке перевіряється із вмістимим регістру BX.

MOV AH, 0

INT 1AH

MOV CL, DELAY

MOV CH, 0

MOV BX, DX

ADD BX, CX

PLAY:

INT 1AH

CMP DX, BX

Якщо вмістиме обох регістрів однакове, то відбувається вимкнення системного динаміка за допомогою команди AND AL, 0FCH і OUT 61H, AL, які пересилають керуюче слово у порт 61Н, чим у свою чергу вимикають системний динамік. Після цього завершується підпрограма міткою endp.

JNE PLAY

IN AL, 61H

AND AL, 0FCH

OUT 61H, AL

Алгоритм роботи програми можна описати такими пунктами:

1. Відображення на екрані текстового інтерфейсу

2. Вивід на екран повідомлення про можливість введення тривалості ноти

3. Читання коду клавіші яка натиснута

4. Перевірка на натиснення клавіш 1−6 (задання тривалості звучання ноти)

5. Якщо клавіша ESC з програми то до пункту 15

6. Якщо клавіша Enter то до пункту 14

7. Якщо клавіша Space 1

8. Читання коду клавіші яка натиснута

9. Перевірка на натиснення клавіш

10. Якщо клавіша ESC з програми то до пункту 15

11. Якщо клавіша Enter то до пункту 14

12. Якщо клавіша Space 1

13. Відтворення звуку після цього до пункту 2

14. Відображення на екрані інтерфейсу довідки, після натиску потрібної клавіші (ESC)переходимо на пункт 1

15. Вихід із програми Графічне відображення алгоритму роботи міститься в Додатку, А РОЗДІЛ 3. ОПИС ПРОГРАМИ ТА АНАЛІЗ ОТРИМАНИХ РЕЗУЛЬТАТІВ звук генерація інтерфейс клавіатура Дана програма призначена для роботи в текстовому режимі в операційній системі MS-DOS. Вона забезпечує програвання нот двох октав, використовуючи клавіатуру в якості емулятора клавіатури музичного інструмента. Також користувач за допомогою цифрових клавіш може керувати тривалістю звучання нот. Програма не вимоглива до апаратного забезпечення та ресурсів комп’ютера, містить надпростий зручний текстовий інтерфейс. Для завершення програми досить натиснути клавішу Esc.

Оскільки ми розробляємо програму яка програє звуки після того як буде нажата потрібна клавіша то ми вносимо потрібні функції які дають змогу зчитувати код натиснутої клавіші, була використана функція 7Н переривання 21Н.

mov ah, 7

int 21h

Очистка екрану від посторонніх символів здійснюється за допомогою переривання int 10h функції 6Н.

MOV AH, 6

MOV AL, 24

MOV CH, 0

MOV CL, 0

MOV DH, 24

MOV DL, 79

MOV BH, 9

INT 10H

Далі на екран виводяться повідомлення за допомогою переривання int 21h функції 9Н

mov dx, OFFSET string

mov ah, 9

int 21h

Для задання тривалості звучання ноти йде цілий блок порівняння вмістимого регістру із клавішами '1'…'6'. За допомогою команди cmp al, 49 порівнюється вмітиме регістра al із значенням 49. Якщо вони нерівні, то відбувається перехід на мітку наступного порівняння, якщо рівні - у змінну DELAY заноситься число, яке відповідає за тривалість звучання ноти.

cmp al, 49

jnz NEXT

mov DELAY, 1

NEXT:

Якщо код відповідає одній із натиснених клавіш, то у змінну DELAY відповідно заноситься певне значення тривалості звучання ноти. Якщо ж код не відповідає даним клавішам, то у змінну DELAY заноситься значення «6» .

Таким самим шляхом, ми зчитуємо наступну натиснуту клавішу, яка повинна відповідати певній ноті.

Таблиця 2.1 відповідності клавіш та нот

Клавіша

Нота звучання

Частота

z

DO

x

RE

c

MI

v

FA

b

SOL

n

LA

m

SI

DO1

s

DO1

d

RE1

f

MI1

g

FA1

h

SOL1

j

LA1

k

SI2

l

DO2

cmp al, 'x'

JNZ GO_

mov dx, OFFSET n1

mov NOTE, 2300

jmp bym

GO_:

Якщо код клавіші співпав із кодом ноти, то при цьому у змінну NOTE заноситься частота звучання відповідної ноти mov NOTE, 2300, у регістр DX заноситься зміщення стрічки, яка є назвою ноти і буде відображатися на екрані і відбувається перехід на підпрограму опрацювання змінних NOTE та DELAY, тобто відбувається перехід на мітку BYM програвання даної ноти із даною затримкою звучання.

Якщо ж код клавіші не співпав із кодами нот та цифрами, то він перевіряється із кодом клавіші Esc.

cmp al, 27

jz EXIT

jmp CONTINUE

Якщо він співпав, то відбувається перехід на мітку завершення програми EXIT. Під час завершення відбувається очищення екрану та вивід повідомлення EXIT_MESSAGE і програма завершується. Якщо код клавіші не співпав із клавішею Esc, то відбувається перехід на мітку CONTINUE і все повторюється спочатку.

При натисненні додаткових клавіш програма виконує додаткові дії.

Так при натисненні клавіші «enter» викликається інформація меню HELP, в якому описано відповідність нажатої клавіші клавіатури та ноти яка повинна прозвучати. Порівняння і відображення довідки відбувається за допомогою

cmp al, 0dh

je help1

help1:

pov:

mov ah, 0

mov al, 2

int 10h

mov ah, 9h

mov dx, offset help

int 21h

poz 23,69

mov ah, 9

mov dx, offset slovo3

int 21h

mov ah, 7

int 21h

cmp al, 1bh

je znov

jmp pov

Повернутися в програму можна нажавши клавішу «esc», при натисненні будь-якої іншої клавіші довідка відображається знову.

Також при натисненні клавіші «space» основна програма запускається ще раз, тобто за допомогою мітки переходить на початок програми.

cmp al, 20h

je znov

Після вдалого запуску програми ви будете бачити вікно програми яке буде мати вигляд який представлений на рис. 3.1

Рис. 3.1

Користувач сам може задати тривалість звучання нот. На екран виводиться позначення ноти, яку натиснув користувач. У будь-який момент програми можна визвати інформаційну допомогу (Рис. 3.2) за допомогою клавіші Enter, ознайомившись з довідкою можна повернутися в попереднє меню натиснувши Esc; розпочати виконання програми заново, натиснувши клавішу Space; та вийти з програми натиснувши Esc.

Рис. 3.2

ВИСНОВКИ Результатом даної курсової роботи є створений програмний продукт на мові Асемблер який забезпечує можливість програвання звуків (нот) різної частоти. Вона містить зручний інтерфейс, використовує клавіатуру для програвання нот та системний динамік для їх озвучення. Забезпечує програвання двох октав з можливістю регулювання тривалості звучання ноти. Дана програма працює тільки під середовищем MS-DOS.

Якщо продовжувати модернізацію даної програми можна добитися різних результатів, наприклад можна запропонувати користувачеві вести порядок програвання звуків певної мелодії, яка запишеться в пам’ять і потім може бути програна, можна також вести звуки півтонів що теж дасть хороший результат. Впродовж всього програмування ми використовували безпосереднє програмування мікросхем 8253 та 8255.

Отже бачимо що мова Асемблер має потужний набір функцій для осягнення такої області культури як музика.

СПИСОК ВИКОРИСТАНИХ ДЖЕРЕЛ

1. Роберт Журден Справочник программиста персональных компьютеров типа IBM, 1992. — 541c.

2. К. Г. Финогенов. Самоучитель по системным функциям MS-DOS. — М.: «Малип», 1993. — 262с.

3. Зубков С. В. Assembler для DOS, Windows и UNIX. — М.:ДМК Пресс, 2000. — 608 с.

4.Орловский Г. В.

Введение

в архітектуру микропроцесора 80 386. Санкт-Петербург: ИНФОКОМ, 1992.-240с.

5.Юров В. Assembler. -СПб.:Питер, 2001.-624с

6. Юров В. Assembler. Практикум. Питер, 2006 г.- 400

7.Владислав Пирогов. Ассемблер для Windows — СПб.: БХВ-Петербург, 2002. — 896 с

8.Калашников О. А. Ассемблер? Это просто! Учимся программировать — БХВ-Петербург, 2005. — С. 374

9.Галисеев Геннадий Владимирович Ассемблер для Win 32. Самоучитель. — М.: «Діалектика», 2007. — С. 368.

10. http://www.codenet.ru/progr/dos/

ДОДАТОК, А БЛОК СХЕМА АЛГОРИТМУ ВИКОНАННЯ ПРОГРАМИ ДОДАТОК Б КОД ПРОГРАМИ

model small

.data

mes db 'PROHRAM$'

string db 'Vuberity trivalisty zvuchannya$'

string1 db 'Zvyk notu :$'

not1 db 'DO$'

not2 db 'RE$'

not3 db 'MI$'

not4 db 'FA$'

not5 db 'SOL$'

not6 db 'LA$'

not7 db 'SI$'

not8 db 'DO1 $'

not9 db 'RE1 $'

not10 db 'MI1 $'

not11 db 'FA1 $'

not12 db 'SOL1 $'

not13 db 'LA1 $'

not14 db 'SI1 $'

not15 db 'DO2 $'

t1 db '1 $'

t2 db '2 $'

t3 db '3 $'

t4 db '4 $'

t5 db '5 $'

t6 db '6 $'

SPACE db ' $'

slovo1 db 'Space-RESTART', 13,10,'$'

slovo2 db 'Enter-HELP', 13,10,'$'

slovo3 db 'Esc-EXIT', 13,10,'$'

help db ' Klavisha — Nota Klavisha — Nota', 13,10

db ' z — Do s — Do (verhnye)', 13,10

db ' x — Re d — Re (verhnye)', 13,10

db ' c — Mi f — Mi (verhnye)', 13,10

db ' v — Fa g — Fa (verhnye)', 13,10

db ' b — Sol h — Sol (verhnye)', 13,10

db ' n — La j — La (verhnye)', 13,10

db ' m — Si k — Si (verhnye)', 13,10,'$'

NOTE dw ('?')

DELAY db ('?')

.stack 128

.386

.code

mov ax,@data

mov ds, ax

poz macro x, y

mov ah, 2

mov bh, 0

mov dh, x

mov dl, y

int 10h

endm

znov:

MOV AH, 6

MOV AL, 24

MOV CH, 0

MOV CL, 0

MOV DH, 24

MOV DL, 79

MOV BH, 1

INT 10H

MOV AH, 2

MOV DH, 1

MOV DL, 22

MOV BH, 0

INT 10H

mov dx, OFFSET mes

mov ah, 9

int 21h

poz 23,69

mov ah, 9h

mov dx, offset slovo2

int 21h

poz 23,34

mov ah, 9h

mov dx, offset slovo1

int 21h

poz 23,1

mov ah, 9h

mov dx, offset slovo3

int 21h

MOV AH, 2

MOV DH, 3

MOV DL, 1

MOV BH, 0

INT 10H

mov dx, OFFSET string

mov ah, 9

int 21h

xor ax, ax

MOV AH, 2

MOV DH, 3

MOV DL, 40

MOV BH, 0

INT 10H

mov ah, 7

int 21h

push ax

cmp al, 0dh

je help1

cmp al, 1dh

je exit

cmp al, 49

jnz NEXT

mov DELAY, 1

mov dx, OFFSET t1

jmp print_t

NEXT:

cmp al, 50

jnz NEXT1

mov DELAY, 2

mov dx, OFFSET t2

jmp print_t

NEXT1:

cmp al, 51

jnz NEXT2

mov DELAY, 3

mov dx, OFFSET t3

jmp print_t

NEXT2:

cmp al, 52

jnz NEXT3

mov DELAY, 4

mov dx, OFFSET t4

jmp print_t

NEXT3:

cmp al, 53

jnz NEXT4

mov DELAY, 5

mov dx, OFFSET t5

jmp print_t

NEXT4:

cmp al, 54

mov DELAY, 6

mov dx, OFFSET t6

jmp print_t

print_t:

mov ah, 9

int 21h

MOV AH, 2

MOV DH, 5

MOV DL, 1

MOV BH, 0

INT 10H

mov dx, OFFSET string1

mov ah, 9

int 21h

CONTINUE:

xor ax, ax

MOV AH, 2

MOV DH, 5

MOV DL, 40

MOV BH, 0

INT 10H

mov ah, 7

int 21h

push ax

mov dx, offset SPACE

mov ah, 9

int 21h

MOV AH, 2

MOV DH, 5

MOV DL, 40

MOV BH, 0

INT 10H

pop ax

cmp al, 0dh

je help1

cmp al, 20h

je znov

cmp al, 'x'

JNZ GO_

mov dx, OFFSET not1

mov NOTE, 2300

jmp bym

GO_:

cmp al, 'c'

JNZ GO1_

mov dx, OFFSET not2

mov NOTE, 2031

jmp bym

GO1_:

cmp al, 'v'

JNZ GO2_

mov dx, OFFSET not3

mov NOTE, 1809

jmp bym

GO2_:

cmp al, 'b'

JNZ GO3_

mov dx, OFFSET not4

mov NOTE, 1709

jmp bym

GO3_:

cmp al, 'n'

JNZ GO4_

mov dx, OFFSET not5

mov NOTE, 1521

jmp bym

GO4_:

cmp al, 'm'

JNZ GO5_

mov dx, OFFSET not6

mov NOTE, 1353

jmp bym

GO5_:

cmp al, ','

JNZ GO6_

mov dx, OFFSET not7

mov NOTE, 1207

jmp bym

GO6_:

cmp al, '.'

JNZ GO7_

mov dx, OFFSET not8

mov NOTE, 1139

jmp bym

GO7_:

cmp al, 'd'

JNZ GO8_

mov dx, OFFSET not9

mov NOTE, 1015

jmp bym

GO8_:

cmp al, 'f'

JNZ GO9_

mov dx, OFFSET not10

mov NOTE, 905

jmp bym

GO9_:

cmp al, 'g'

JNZ GO10_

mov dx, OFFSET not11

mov NOTE, 854

jmp bym

GO10_:

cmp al, 'h'

JNZ GO11_

mov dx, OFFSET not12

mov NOTE, 760

jmp bym

GO11_:

cmp al, 'j'

JNZ GO12_

mov dx, OFFSET not13

mov NOTE, 676

jmp bym

GO12_:

cmp al, 'k'

JNZ GO13_

mov dx, OFFSET not14

mov NOTE, 603

jmp bym

GO13_:

cmp al, 'l'

JNZ GO14_

mov dx, OFFSET not15

mov NOTE, 569

jmp bym

GO14_:

cmp al, 's'

JNZ GO15_

mov dx, OFFSET not8

mov NOTE, 1139

jmp bym

GO15_:

cmp al, 27

jz EXIT

jmp CONTINUE

bym:

mov ah, 9

int 21h

call zvyk

jmp CONTINUE

help1:

pov:

mov ah, 0

mov al, 2

int 10h

mov ah, 9h

mov dx, offset help

int 21h

poz 23,69

mov ah, 9

mov dx, offset slovo3

int 21h

mov ah, 7

int 21h

cmp al, 1bh

je znov

jmp pov

EXIT:

mov ax, 4c00h

int 21h

zvyk proc

IN AL, 61h

OR AL, 11B

OUT 61h, AL

MOV AL, 0B6H

OUT 43h, AL

MOV DX, NOTE

MOV AL, DL

OUT 42H, AL

MOV AL, DH

OUT 42H, AL

MOV AH, 0

INT 1AH

MOV CL, DELAY

MOV CH, 0

MOV BX, DX

ADD BX, CX

PLAY:

INT 1AH

CMP DX, BX

JNE PLAY

IN AL, 61H

AND AL, 0FCH

OUT 61H, AL

ret

zvyk endp

end

Показати весь текст
Заповнити форму поточною роботою