Инструменты пользователя

Инструменты сайта


msx:basic_dialogue_programming_language:107

Различия

Здесь показаны различия между двумя версиями данной страницы.

Ссылка на это сравнение

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
msx:basic_dialogue_programming_language:107 [2023-01-23 19:29]
GreyWolf
msx:basic_dialogue_programming_language:107 [2023-02-18 18:12] (текущий)
GreyWolf
Строка 2: Строка 2:
 ~~TOC wide~~ ~~TOC wide~~
  
 +{{anchor:​n107}}
 ====== 1.7. Программирование звуковых эффектов ====== ====== 1.7. Программирование звуковых эффектов ======
 FIXME FIXME
  
-Мы уже говорили о возможностях работы с Программируемым Звуковым Генератором — PSG. Здесь мы расскажем Вам о работе с PSG  при программировании в машинных кодах.+Мы уже говорили о возможностях работы с Программируемым Звуковым Генератором — PSG. Здесь мы расскажем Вам о работе с PSG при программировании в машинных кодах.
  
 Вначале кратко //​повторим//​ основные сведения. Вначале кратко //​повторим//​ основные сведения.
Строка 17: Строка 18:
 |  4  |Младший байт частоты канала C| |  4  |Младший байт частоты канала C|
 |  5  |Старший байт частоты канала C| |  5  |Старший байт частоты канала C|
-|  6  |Частота шума ​ |+|  6  |Частота шума|
 |  7  |Выбор звучания каналов| |  7  |Выбор звучания каналов|
 |  8  |Громкость канала A| |  8  |Громкость канала A|
Строка 25: Строка 26:
 |  12  |Старший байт периода волны| |  12  |Старший байт периода волны|
 |  13  |Указатель формы волны| |  13  |Указатель формы волны|
 +
 +Звуки бывают двух типов, которые мы назовем "​звук"​ и "​шум"​. За сочетание звучания "​звука"​ и "​шума"​ отвечает 7–й регистр PSG:
  
 <​code>​ <​code>​
-   ​Звуки бывают двух типов, которые мы назовем "​звук"​ и "​шум"​. За сочета- 
-ние звучания "​звука"​ и "​шума"​ отвечает 7-й регистр PSG: 
    ​бит 7 бит 6   ​бит 5    бит 4    бит 3    бит 2    бит 1    бит 0    ​бит 7 бит 6   ​бит 5    бит 4    бит 3    бит 2    бит 1    бит 0
   ┌─────┬─────┬────────┬────────┬────────┬────────┬────────┬────────┐   ┌─────┬─────┬────────┬────────┬────────┬────────┬────────┬────────┐
Строка 35: Строка 36:
      ​│ ​    ​│ ​     │        │         ​│ ​      ​│ ​        ​│ ​       │      ​│ ​    ​│ ​     │        │         ​│ ​      ​│ ​        ​│ ​       │
   Не используются └─── Выбор"​шума"​───┘ ​      ​└── Выбор"​звука"​ ──┘   Не используются └─── Выбор"​шума"​───┘ ​      ​└── Выбор"​звука"​ ──┘
-   ​Частота звучания "​звука"​ из некоторого канала (A,B или C) определяется +</​code>​
-по следующей формуле:​ +
-        1789772.5 Гц +
-        ──────────── = значение в регистрах для канала A, B или C +
-         ​16·частота +
-   По той же формуле вычисляется частота звучания "​шума"​(значение берется +
-из регистра с номером 6). +
-   ​Период волны определяется по следующей формуле:​ +
-            1789772.5 Гц +
-           ​───────────── = значение в регистрах 11 и 12. +
-             ​256·период +
-   ​Работа звукового генератора поддерживается процессором через порты вво- +
-да-вывода со следующими адресами:​ +
-             ​┌──────┬───────────────────────────────────────┐ +
-             │ Порт │          Н а з н а ч е н и е          │ +
-             ​├──────┼───────────────────────────────────────┤ +
-             ​│ ​ A0h │ Номер регистра PSG для записи числа ​  │ +
-             ​│ ​ A1h │ Число для записи в отмеченный регистр │ +
-             ​│ ​ A2h │ Последнее число, записанное в PSG     │ +
-             ​└──────┴───────────────────────────────────────┘ +
-   ​Существует два способа записи чисел в PSG средствами языка MSX-BASIC:​ +
-   α) SOUND reg, data +
-   β) OUT &​HA0,​reg:​OUT &​HA1,​data +
-   П р и м е р 1.  Программа в машинных кодах, записывающая число ​ 254  в +
-   ​───────────── ​  ​звуко-генератор (в регистр 0). +
-   10 CLEAR 200,&​HF000:​DEFUSR=&​HF000 +
-   20 DATA 3E,00 :' LD  A,0 +
-   30 DATA D3,A0 :' OUT (A0h),A +
-   40 DATA 3E,FE :' LD  A,FEh +
-   50 DATA D3,A1 :' OUT (A1h),A +
-   60 DATA C9    :' RET +
-   70 DATA RET +
-   80 READ Z$ +
-   90 IF Z$="​RET"​ THEN 110 +
-   100 POKE &​HF000+T,​VAL("&​h"​+Z$):​T=T+1:​GOTO 80 +
-   110 A=USR(A) +
-   ​Следующая таблица поможет Вам при моделировании оператора ​ PLAY  в ма- +
-шинных кодах (данные приведены для канала A):+
  
 +Частота звучания "​звука"​ из некоторого канала (A,B или C) определяется по следующей формуле:​
 +<​code>​
 +1789772.5 Гц
 +──────────── = значение в регистрах для канала A, B или C
 + ​16·частота
 +</​code>​
 +По той же формуле вычисляется частота звучания "​шума"​(значение берется из регистра с номером 6).
  
 +Период волны определяется по следующей формуле:​
 +<​code>​
 + ​1789772.5 Гц
 +───────────── = значение в регистрах 11 и 12.
 +  256·период
 +</​code>​
 +Работа звукового генератора поддерживается процессором через порты ввода–вывода со следующими адресами:​
 +^  Порт ​ ^  //​Назначение// ​ ^
 +|  A0h  |  Номер регистра PSG для записи числа ​ |
 +|  A1h  |  Число для записи в отмеченный регистр ​ |
 +|  A2h  |  Последнее число, записанное в PSG  |
  
 +Существует два способа записи чисел в PSG средствами языка [[msx:​basic:​|]]:​
 +  * α) <​code>​SOUND reg, data</​code>​
 +  * β) <​code>​OUT &​HA0,​reg:​OUT &​HA1,​data</​code>​
  
 +{{anchor:​e1070-01}} __//​Пример 1//__. Программа в машинных кодах, записывающая число 254 в звукогенератор (в регистр 0).\\ {{.examples:​1070-01.bas|}} \\ [[+tab|wmsxbpge>​1070-01.bas]]
 +<​code>​
 +10 CLEAR 200,&​HF000:​DEFUSR=&​HF000
 +20 DATA 3E,00 :' LD  A,0
 +30 DATA D3,A0 :' OUT (A0h),A
 +40 DATA 3E,FE :' LD  A,FEh
 +50 DATA D3,A1 :' OUT (A1h),A
 +60 DATA C9    :' RET
 +70 DATA RET
 +80 READ Z$
 +90 IF Z$="​RET"​ THEN 110
 +100 POKE &​HF000+T,​VAL("&​h"​+Z$):​T=T+1:​GOTO 80
 +110 A=USR(A)
 +</​code>​
  
 +Следующая таблица поможет Вам при моделировании оператора ''​PLAY''​ в машинных кодах (данные приведены для канала A):
  
-       ​┌───────┬────┬─────┬─────┐ ​    ​┌───────┬────┬─────┬─────┐ +|<30% 25% 15% 15% 15%>| 
-       │Октава ​НотаРег.0Рег.1│     │Октава ​│Нота│Рег.0│Рег.1│ +^  ​Октава ​ ​^  ​Нота ​^  ​Рег.0 ​ ​^  ​Рег.1 ​ ^ 
-       ​├───────┼────┼─────┼─────┤ ​    ​├───────┼────┼─────┼─────┤ +|  O1 \\ (контр–октава)  |C 93|  ​13  ​| 
-       ​│ ​      ​│ ​C  ​│  93 │ 13  ​│     ​│ ​      │ C  │ 214 │  0  │ +|:::|C#|  ​156|  ​12  ​| 
-       │  O1   ​│ ​C# │ 156 │ 12  ​│     ​│ ​ O5   │ C# │ 202 │  0  │ +|::: |D 231|  ​11  ​| 
-       │       ​│ ​D  ​│ 231 │ 11  ​│     ​│ ​      │ D  │ 190 │  0  │ +|:::|D# 60|  ​11  ​| 
-       │(контр-│ ​D# │  ​60 ​│ 11  ​│     │ (вто- │ D# │ 180 │  0  │ +|:::|E 155|  ​10  ​| 
-       │октава)│ ​E  ​│ 155 │ 10  ​│     ​│ ​ рая) │ E  │ 170 │  0  │ +|:::|F  2|  ​10  ​| 
-       │       ​│ ​ ​│ ​  2 │ 10  ​│     ​│ ​      │ F  │ 160 │  0  │ +|:::|F#|  ​115 ​9  ​| 
-       │       ​│ ​F# │ 115 │  ​9  ​│     ​│ ​      │ F# │ 151 │  0  │ +|:::|G 235 ​8  ​| 
-       │       ​│ ​G  ​│ 235 │  ​8  ​│     ​│ ​      │ G  │ 143 │  0  │ +|:::|G#|  ​107 ​8  ​| 
-       │       ​│ ​G# │ 107 │  ​8  ​│     ​│ ​      │ G# │ 135 │  0  │ +|:::|A 242 ​7  ​| 
-       │       ​│ ​A  ​│ 242 │  ​7  ​│     ​│ ​      │ A  │ 127 │  0  │ +|:::|A#|  ​128 ​7  ​| 
-       │       ​│ ​A# │ 128 │  ​7  ​│     ​│ ​      │ A# │ 120 │  0  │ +|:::|B 20 ​7  ​
-       │       ​│ ​ ​│ ​ ​20 ​│  ​7  ​│     ​│ ​      │ B  │ 113 │  0  │ + O2 \\ (большая) ​ |C 175 ​6  ​
-       ​├───────┼────┼─────┼─────┤ ​    ​├───────┼────┼─────┼─────┤ +|:::| C# |  78|   | 
-       ​│ ​      ​│ ​C  ​│ 175 │  ​6  ​│     ​│ ​      ​│ ​C  ​│ 107 │    +|:::| D  |  244|  5  | 
-       │  O2   │ C│  ​78 ​│   │     ​│ ​ O6   ​│ C# │ 101 │    +|:::| D|  158|  5  | 
-       │       │ D  │ 244 │   │     ​│ ​      │ D  │  95 │    +|:::| E  |  78  
-       │ (боль-│ D│ 158 │   │     │ (тре- │ D│  90 │    +|:::| F    ​1|   | 
-       │  шая) │ E  │  78 │   │     ​│ ​ тья) │ E  │  85 │    +|:::| F# |  186|   
-       │       │ F  │   1 │   │     ​│ ​      │ F  │  80 │    +|:::| G   118|   | 
-       │       ​│ ​F# │ 186 │   │     ​│ ​      ​│ ​F# │  76 │    +|:::| G 54|  4  | 
-       │       │ G  │ 118 │  4  │     ​│ ​      ​│ ​G  ​│  71 │    +|:::| A  |  249|  3  | 
-       │       ​│ ​G# │  54 │   │     ​│ ​      │ G# │  67 │    +|:::| A 192|   | 
-       │       ​│ ​A  ​│ 249 │   │     ​│ ​      │ A  │  64 │    +|:::| B  |  138|  3  | 
-       │       │ A# │ 192 │   │     ​│ ​      │ A│  60 │    +|  O3 \\ (малая)  ​| C   87|   
-       │       │ B  │ 138 │   │     ​│ ​      │ B  │  57 │    +|:::| C# |  39|   
-       ├───────┼────┼─────┼─────┤ ​    ​├───────┼────┼─────┼─────┤ +|:::| D  |  250|  2  | 
-       ​│ ​      │ C  │  87 │   │     ​│ ​      │ C  │  53 │    +|:::| D# |  207|   
-       │  O3   │ C│  39 │   │     ​│ ​ O7   │ C│  50 │  ​0  ​ +|:::| E   167|   | 
-       │       │ D  │ 250 │   │     ​│ ​      │ D  │  48 │  ​0  ​ +|:::| F  ​ 129|  2  | 
-       │(малая)│ D# │ 207 │   │     │ (чет- │ D# │  45 │  ​0  ​ +|:::| F#  93|   | 
-       │       │ E  │ 167 │   │     ​│ ​ вер- │ E  │  42 │  ​0  ​ +|:::|  ​G  ​ 59|   | 
-       │       │ F  │ 129 │   │     ​│ ​ тая) │ F  │  40 │  ​0  ​ +|:::| G#  27|   
-       │       ​│ ​F# │  93 │   │     ​│ ​      ​│ ​F# │  38 │  ​0  ​ +|:::| A   253|  1  | 
-       │       ​│ ​G  ​│  59 │   │     ​│ ​      ​│ ​G  ​│  36 │  ​0  ​ +|:::| A# |  224|   
-       │       │ G# │  27 │   │     ​│ ​      │ G│  34 │  ​0  ​ +|:::| B   197|   | 
-       │       │ A  │ 253 │   │     ​│ ​      │ A  │  32 │  ​0  ​ + O4 \\ (первая) ​ | C  |  172|  1  | 
-       │       │ A│ 224 │   │     ​│ ​      │ A# │  30 │  ​0  ​ +|:::| C 148|   | 
-       │       │ B  │ 197 │   │     ​│ ​      │ B  │  28 │  ​0  ​ +|:::| D   125|   
-       ├───────┼────┼─────┼─────┤ ​    ​├───────┼────┼─────┼─────┤ +|:::| D# |  104|   | 
-       ​│ ​      │ C  │ 172 │   │     ​│ ​      │ C  │  27 │  ​0  ​ +|:::| E   83|   
-       │  O4   │ C# │ 148 │   │     ​│ ​ O8   │ C│  25 │  ​0  ​ +|:::| F   64|   | 
-       │       │ D  │ 125 │   │     ​│ ​      │ D  │  24 │  ​0  ​ +|:::| F 46|   
-       │ (пер- │ D# │ 104 │   │     │(пятая)│ D│  22 │  ​0  ​ +|:::| G  |  29|  1  | 
-       │  вая) │ E  │  83 │   │     ​│ ​      ​│ ​E  ​│  21 │  ​0  ​ +|:::| G 13|  1  | 
-       │       ​│ ​F  ​│  64 │   │     ​│ ​      ​│ ​F  ​│  20 │  ​0  ​ +|:::| A  |  254|  ​0  ​| 
-       │       │ F│  46 │   │     ​│ ​      │ F│  19 │  ​0  ​ +|:::| A# |  240|   
-       │       │ G  │  29 │   │     ​│ ​      │ G  │  18 │  ​0  ​ +|:::| B   227|  ​0  ​| 
-       │       │ G│  13 │   │     ​│ ​      │ G│  17 │  ​0  ​ +|  O5 (вторая)  ​| C   214|  ​0  ​| 
-       │       │ A  │ 254 │  ​0  ​│     ​│ ​      │ A  │  16 │  ​0  ​ +|:::| C# |  202|   
-       │       │ A│ 240 │  ​0  ​│     ​│ ​      │ A│  15 │  ​0  ​ +|:::| D   190|  ​0  ​| 
-       │       │ B  │ 227 │  ​0  ​│     ​│ ​      ​│ ​B  ​│  ​14 ​│  ​0  ​│ +|:::| D# |  180|   
-       ​└───────┴────┴─────┴─────┘ ​    ​├───────┼────┼─────┼─────┤ +|:::| E   170|  ​0  ​| 
-                                      │(шестая)  ​- │  ​13 ​│  ​0  ​│ +|:::| F  ​ 160|  0  | 
-                                      └───────┴────┴─────┴─────┘+|:::| F#  151|  ​0  ​| 
 +|:::| G  ​ 143|   
 +|:::| G# |  135|  ​0  ​| 
 +|:::| A   127|  0  | 
 +|:::| A 120|  ​0  ​| 
 +|:::| B   113|   
 + O6 \\ (третья) ​ | C  |  107|  ​0  ​| 
 +|:::| C 101|   
 +|:::| D  |  95|  ​0  ​| 
 +|:::| D# |  90|   
 +|:::| E   85|  ​0  ​| 
 +|:::| F   80|   
 +|:::| F# |  76|  ​0  ​| 
 +|:::| G   71|   
 +|:::| G 67|  ​0  ​| 
 +|:::| A   64|   
 +|:::| A# |  60|  ​0  ​| 
 +|:::| B   57|  0  | 
 +|  O7 \\ (четвёртая) ​ | C  |  53|  0  | 
 +|:::| C 50|  ​0  ​| 
 +|:::| D   48|   
 +|:::| D# |  45|  0  | 
 +|:::| E  ​ 42|  ​0  ​| 
 +|:::| F  ​ 40|   
 +|:::| F# |  38|  0  | 
 +|:::| G  |  36|  ​0  ​| 
 +|:::| G 34|   
 +|:::| A  |  32|  0  | 
 +|:::| A 30|  ​0  ​| 
 +|:::| B   28|   
 + O8 \\ (пятая) ​ | C  |  27|  ​0  ​| 
 +|:::| C 25|   
 +|:::| D  |  24|  0  | 
 +|:::| D 22|  ​0  ​| 
 +|:::| E  |  21|  ​0  ​
 +|:::| F   20|  ​0  ​| 
 +|:::| F|  19|  ​0  ​
 +|:::| G  |  18|  0  | 
 +|:::| G 17|  ​0  ​| 
 +|:::| A  |  16|  ​0  ​
 +|:::| A# |  15|  0  | 
 +|:::| B  ​ 14 ​0  ​| 
 +|(шестая) —  |  13 ​0  ​|
  
-   П р и м е р 2.  Программа,​ позволяющая прочесть данные ​ из звукогенера+{{anchor:​e1070-02}} __//Пример 2//__. Программа,​ позволяющая прочесть данные из звукогенератора и проверить приведённую таблицу.\\ {{.examples:​1070-02.bas|}} \\ [[+tab|wmsxbpge>​1070-02.bas]] 
-   ​──────────────  ​тора и проверить приведенную таблицу. +<​code>​ 
-   ​10 CLEAR 200,&​HF000:​DEFUSR=&​HF000 +10 CLEAR 200,&​HF000:​DEFUSR=&​HF000 
-   ​20 DATA CD,​1F,​52 ​      :'​CALL 521F ; +20 DATA CD,​1F,​52 ​      :'​CALL 521F ; 
-   ​30 DATA CD,​96,​00 ​      :'​CALL 0096 ; Чтение числа из PSG +30 DATA CD,​96,​00 ​      :'​CALL 0096 ; Чтение числа из PSG 
-   ​40 DATA 26,00          :'​LD ​  ​H,​0 ​ ; +40 DATA 26,00          :'​LD ​  ​H,​0 ​ ; 
-   ​50 DATA 6F             :'​LD ​  ​L,​A ​ ; +50 DATA 6F             :'​LD ​  ​L,​A ​ ; 
-   ​60 DATA C3,​99,​2F,"​RET"​ :'​JP ​  2F99 ; +60 DATA C3,​99,​2F,"​RET"​ :'​JP ​  2F99 ; 
-   ​70 READ Z$ +70 READ Z$ 
-   ​80 IF Z$="​RET"​ THEN 100 +80 IF Z$="​RET"​ THEN 100 
-   ​90 POKE &​HF000+T,​VAL("&​h"​+Z$):​T=T+1:​GOTO 70 +90 POKE &​HF000+T,​VAL("&​h"​+Z$):​T=T+1:​GOTO 70 
-   ​100 PLAY "O4 C#" +100 PLAY "O4 C#" 
-   ​110 PRINT USR(0);​USR(1) '​Читаем содержимое 0-го и 1-го регистров+110 PRINT USR(0);​USR(1) '​Читаем содержимое 0го и 1го регистров 
 +</​code>​
  
 +{{anchor:​n1071}}
 +===== Фоновое музыкальное сопровождение =====
 +(Данный раздел написан А.Н.Никитиным)
  
-     ​Ф ​о н о в о е  м у з ы к а л ь н о е  с о п р о в о ж д е н и е+Существует несколько вариантов реализации фонового сопровождения программы. Вспомним один из рутинных вариантов воплощения фонового ​музыкального сопровождения. Зная, что длительность нот намного превышает время выполнения процессором арифметических операций,​ можно установить соответствие между музыкальной длительностью ​и определённым количеством арифметических операций,​ выполняемых процессором. Далее остаётся последовательно вставлять музыкальные фрагменты (их длина, разумеется,​ должна быть ограничена настолько,​чтобы программа не "​зависала"​!) между операторами основной программы. Ясно, что такой способ вызывает массу неудобств:​ значительно усложняется редактирование программы,​ программирование требует огромных затрат времени и труда, об универсальности программы не может быть и речи.
  
-\fc +Предлагаемый нами алгоритм реализации фонового музыкального сопровождения полностью //исключает// перечисленные неудобства!
-                 (Данный раздел написан А.Н.Никитиным) +
-\f-c-+
  
-   ​Существует несколько вариантов реализации фонового ​ сопровождения ​ про- +Расскажем Вам идею алгоритма. Во время работы процессор совершает маскируемые прерывания частотой 5О Гц и опрашивает область ловушек (hooks),а точнее происходят обращения (CALL ...) по адресам FD9Ah, FD9Fh. Напомним Вам, что эти прерывания разрешаются командой ассемблера EI, а запрещаются командой DI. Начальный адрес Таблицы ловушек ​— &hFD9A. По этому адресу системной области хранится подпрограмма перехода на программу сетевого обмена у компьютеров серии MSX-2 и число &​HC9(машинный код команды RET) у компьютеров серии MSX-1, поэтому при обращении к данной ловушке либо из подпрограммы обработки прерываний (которая расположена по адресу 0038h), либо из Вашей программы означает мгновенный возврат в основную программу (если MSX-2 не ведёт "​сетевой диалог"​). 
-граммы. Вспомним один из рутинных вариантов воплощения ​ фонового музыкаль- + 
-ного сопровождения. Зная, что длительность нот намного превышает время вы- +Если по адресу FD9Ah "​положить"​ подпрограмму:​ 
-полнения процессором арифметических операций,​ можно установить ​ соответст- +<WRAP group> 
-вие между музыкальной длительностью и определенным ​ количеством ​ арифмети- +<WRAP half column>​ 
-ческих операций,​ выполняемых процессором. Далее ​ остается последовательно +<​code>​ 
-вставлять музыкальные фрагменты (их длина, разумеется,​ должна быть ограни- +RST    30h 
-чена настолько,​чтобы программа не "​зависала"​!) между операторами основной +DEFB   ​N_slot 
-программы. Ясно, что такой способ вызывает ​ массу ​ неудобств:​ значительно +DEFW   ​Adres 
-усложняется редактирование программы,​ программирование ​ требует ​ огромных +RET            
-затрат времени и труда, об универсальности программы не может быть и речи. +</​code>​ 
-   ​Предлогаемый нами алгоритм реализации фонового музыкального сопровожде- +</​WRAP>​ 
-ния полностью ​ и с к л ю ч а е т  перечисленные неудобства! + 
-   Расскажем Вам идею алгоритма. Во время работы процессор совершает ​ мас+<WRAP half column>​ 
-кируемые прерывания частотой 5О Гц и опрашивает область ловушек (hooks),а +, 
-точнее происходят обращения (CALL ...) по адресам FD9Ah, FD9Fh. ​ Напомним +</​WRAP>​ 
-Вам, что эти прерывания разрешаются командой ассемблера EI, а запрещаются +</​WRAP>​ 
-командой DI. Начальный адрес Таблицы ловушек ​&hFD9A. По этому адресу си+где N_slot ​— это номер слота, в котором будет расположена Ваша программа,​ а Adres — это адрес Вашей подпрограммы обработки прерываний,​ то 50 раз в секунду управление будет передаваться Вашей подпрограмме,​ в которой можно управлять музыкой,​ печатью,​ графикой или опрашивать клавиатуру. 
-стемной области хранится подпрограмма перехода на программу сетевого обме+ 
-на у компьютеров серии MSX-2 и число &​HC9(машинный код команды RET) у ком+Вообще говоря,​число 50 не очень удобно для точного отсчёта музыкальной длительности (так как 50 не делится на 8, 16, 32; в этом смысле идеальным было бы число 64), но при сравнении длительностей между собой (а не с метрономом) искажение звука практически незаметно. 
-пьютеров серии MSX-1, поэтому при обращении к данной ловушке либо из  под+ 
-программы обработки прерываний (которая расположена по адресу 0038h),​либо +Структура музыкальной подпрограммы довольно проста:​ она должна обрабатывать данные и управлять музыкальными очередями. Вся сложность состоит в том, чтобы построить такую структуру музыкальных данных,​ которая удовлетворяла бы следующим требованиям:​ объем данных должен быть минимальным,​ возможности управления музыкальным генератором должны быть большими,​ должны присутствовать элементы программирования (циклы,​переходы и т.д.), должно выполняться большинство музыкальных выражений (Legato, Staccato и т.д.). 
-из Вашей программы означает мгновенный возврат в основную программу (если + 
-MSX-2 не ведет "​сетевой диалог"​). +В предложенном ниже описании структуры музыкальных данных,​ мы постарались удовлетворить лишь части названных требований.Структура данных очень напоминает стандарт MIDIинтерфейса(Musical Instrument Digital Interface). 
-   ​Если по адресу FD9Ah "​положить"​ подпрограмму:​ + 
-                        RST    30h +Порядок размещения данных в очереди следующий:​ 
-                        DEFB   ​N_slot +<​code>​ 
-                        DEFW   ​Adres +<​Команда>,​{Данное},​{Данное},<​Команда>,​{Данное},​{Данное},​... 
-                        RET           , +</​code>​
-где ​ N_slot ​это номер слота, в котором будет расположена Ваша программа,​ +
-а  Adres это адрес Вашей подпрограммы обработки прерываний,​ то 50 раз в  +
-секунду управление будет передаваться Вашей подпрограмме,​ в которой можно +
-управлять музыкой,​ печатью,​ графикой или опрашивать клавиатуру. +
-   ​Вообще говоря,​число 50 не очень удобно для точного отсчета музыкальной +
-длительности (так как 50 не делится на 8, 16, 32; в этом смысле идеальным +
-было бы число 64), но при сравнении длительностей между собой (а не с мет+
-рономом) искажение звука практически незаметно. +
-   ​Структура музыкальной подпрограммы довольно проста:​ она должна ​ обраба+
-тывать данные и управлять музыкальными очередями. Вся сложность состоит в +
-том, чтобы построить такую структуру музыкальных данных,​ которая ​ удовлет+
-воряла бы следующим требованиям:​ объем данных должен быть минимальным,​воз+
-можности управления музыкальным генератором должны быть ​ большими,​ должны +
-присутствовать элементы программирования (циклы,​переходы ​ и т.д.), должно +
-выполняться большинство музыкальных выражений (Legato, Staccato и т.д.). +
-   ​В предложенном ниже описании структуры музыкальных данных,​ мы  постара+
-лись удовлетворить лишь части названных требований.Структура данных очень +
-напоминает стандарт MIDI-интерфейса(Musical Instrument Digital Interface). +
-   ​Порядок размещения данных в очереди следующий:​ +
-        <​Команда>,​{Данное},​{Данное},<​Команда>,​{Данное},​{Данное},​...+
 Следует отметить,​ что {Данное} может быть опущено. Следует отметить,​ что {Данное} может быть опущено.
-   Приведем описание команд и данных. + 
-К о м а н д а  0Установка частоты (высоты) звучания:​ +Приведём описание команд и данных. 
-   1 полубайт ​команда 00 ; 2 полубайт ​номер ноты 1÷12. + 
-К о м а н д а  ​1Микширование (регистр 7 PSG,по умолчанию ​&​hb10111000):​ +^  //Команда//  ^  Описание ​ ^ 
-   1 полубайт ​команда 01 , 2 полубайт ​формальный , +|0|Установка частоты (высоты) звучания: ​\\ 1 полубайт ​— команда 00 ; 2 полубайт ​— номер ноты 1÷12.| 
-   следующий байт ​байт состояния (структура аналогична структуре данных,​ +|1|Микширование (регистр 7 PSG,по умолчанию ​— &​hb10111000): ​\\ 1 полубайт ​— команда 01 , 2 полубайт ​— формальный , следующий байт ​— байт состояния (структура аналогична структуре данных,​ находящихся в регистре 7): <​code>​ 
-находящихся в регистре 7): +&b10 ∗∗∗ ∗∗∗ 
-            &b10 ∗∗∗ ∗∗∗ +     ​▲▲▲ ▲▲▲ 
-                 ​▲▲▲ ▲▲▲ +     ​│││ │││ 
-                 ​│││ │││ +     ​cba cba — номера каналов 
-                 ​cba cba номера каналов +     ​Шум Сигнал 
-                 ​Шум Сигнал +</​code>​| 
-К о м а н д а  ​2Установка темпа воспроизведения (по умолчанию ​1): +|2|Установка темпа воспроизведения (по умолчанию ​— 1): \\ 1 полубайт ​— команда 02 ; 2 полубайт ​— данное (1÷2).| 
-   1 полубайт ​команда 02 ; 2 полубайт ​данное (1÷2). +|3|Установка амплитуды звучания (по умолчанию ​— 8): \\ 1 полубайт ​— команда 03, 2 полубайт ​— данное (0÷15) (амплитуда = данное + 1).| 
-К о м а н д а  ​3Установка амплитуды звучания (по умолчанию ​8): +|4|Установка частоты шума (по умолчанию ​— 20): \\ 1 полубайт ​— команда 04, 2 полубайт ​— данное (1÷15, частота = данное·2).| 
-   1 полубайт ​команда 03, +|5|Установка формы волны (пакета): ​\\ 1 полубайт ​— команда 05 , 2 полубайт ​— данное (1÷15).| 
-   2 полубайт ​данное ​ (0÷15) (амплитуда = данное + 1). +|6|Установка значения для 11 регистра PSG(по умолчанию ​— 100) \\ 1 полубайт ​— команда 06, 2 полубайт ​— данное (0÷15, значение = данное · 10).| 
-К о м а н д а  ​4Установка частоты шума (по умолчанию ​20): +|7|Установка значения для 12 регистра PSG(по умолчанию ​— 10): \\ 1 полубайт ​— команда 07, 2 полубайт ​— данное (0÷15, значение=данное·2).| 
-   1 полубайт ​команда 04, +|8|Установка текущей длительности звучания: ​\\ 1 полубайт ​— команда 08, \\ 2 полубайт ​— данное (1÷15), где ​<​WRAP>​ 
-   2 полубайт ​данное (1÷15, частота = данное·2). +  — целая с точкой,​ 
-К о м а н д а  ​5Установка формы волны (пакета):​ +  — целая, 
-   1 полубайт ​команда 05 , 2 полубайт ​данное (1÷15). +  * — половинная с точкой,​ 
-К о м а н д а  ​6Установка значения для 11 регистра PSG(по умолчанию-100) +  ​* ​— половинная,​ 
-   1 полубайт ​команда 06, +  * — четвертная с точкой,​ 
-   2 полубайт ​данное (0÷15, значение = данное · 10). +  * — четвертная,​ 
-К о м а н д а  ​7Установка значения для 12 регистра PSG(по умолчанию-10): +  ​* ​— восьмая с точкой,​ 
-   1 полубайт ​команда 07, 2 полубайт ​данное (0÷15, значение=данное·2). +  * — восьмая,​ 
-К о м а н д а  ​8.  ​Установка текущей длительности звучания:​ +  * — шестнадцатая с точкой,​ 
-   1 полубайт ​команда 08, 2 полубайт ​данное (1÷15), +  ​* ​10 — шестнадцатая,​ 
-     где ​ 1 целая с точкой, ​ 2 целая, 3 половинная с точкой,​ +  * 11 — тридцатьвторая с точкой,​ 
-          половинная,​ 5 четвертная с точкой,​ 6 четвертная,​ +  ​* ​12 — тридцатьвторая. 
-          восьмая с точкой,​ 8 восьмая,​ 9 шестнадцатая с точкой,​ +</​WRAP>​| 
-         ​10 шестнадцатая,​ 11 тридцатьвторая с точкой,​ +|9|Пауза: ​\\ 1 полубайт ​— команда 09, 2 полубайт ​— формальный.| 
-         ​12 тридцатьвторая. +|10|Переход (CALL или JUMP) по адресу данных ​\\ 1 полубайт ​— команда 10 , 2 полубайт ​— формальный,​ следующие два байта ​— относительный адрес данных от расположения всех музыкальных данных.| 
-К о м а н д а  ​9.  ​Пауза: +|11|Возврат из подпрограммы (адреса хранятся "у себя"​) ​\\ Возвращаться можно сколь угодно раз (ибо это не стек)! ​\\ 1 полубайт ​— команда 11 , 2 полубайт ​— формальный.| 
-   1 полубайт ​команда 09, 2 полубайт ​формальный. +|12|Стоп, выключить канал: ​\\ 1 полубайт ​— команда 12, 2 полубайт ​— формальный.| 
-К о м а н д а 10Переход (CALL или JUMP) по адресу данных +|13|Установка текущей октавы: ​\\ 1 полубайт ​— команда 13, 2 полубайт ​— номер октавы (1,​2,​3,​...,​8).| 
-   1 полубайт ​команда 10 , 2 полубайт ​формальный,​ следующие два байта+|14|Приём игры (Staccato, Legato): ​\\ 1 полубайт ​— команда 14, 2 полубайт ​— 1, если Staccato и 0, если Legato. ​\\ Заметим,​ что числа от 2 до 15 могут выражать и другие приёмы игры!| 
-   относительный адрес данных от расположения всех музыкальных данных. +|15|Резервная: ​\\ 1 полубайт ​— команда 15, 2 полубайт ​— ... (можно использовать как передачу других команд,​ т.е. 15я команда становится ​//префиксной//).
-К о м а н д а 11Возврат из подпрограммы (адреса хранятся "у себя"​) + 
-                  ​Возвращаться можно сколь угодно раз (ибо это не стек)! +Таким образом,​ Ваша подпрограмма должна распознавать номер команды,​ исполнять её, исходя из параметров,​ следующих за командой и помещать указатель данных на следующую команду. Если Вы желаете увеличить музыкальные возможности программы,​а команд (в полубайт можно поместить число от 0 до 15) не хватает,​ то необходимо выделить префиксную команду (например,​ 15ю, так как она резервная)и теперь порядок размещения данных в очереди станет следующим:​ 
-   1 полубайт ​команда 11 , 2 полубайт ​формальный. +<​code>​ 
-К о м а н д а 12Стоп, выключить канал: +<​Команда>,<​Команда>,​{данное},​{данное},​... 
-   1 полубайт ​команда 12, 2 полубайт ​формальный. +<​Команда>,<​Команда>,​{данное},​{данное},​...
-К о м а н д а 13Установка текущей октавы:​ +
-   1 полубайт ​команда 13, 2 полубайт ​номер октавы (1,​2,​3,​...,​8). +
-К о м а н д а 14Прием игры (Staccato, Legato): +
-   1 полубайт ​команда 14, +
-   2 полубайт ​1, если Staccato и 0, если Legato. +
-   Заметим,​ что числа от 2 до 15 могут выражать и другие приемы игры! +
-К о м а н д а 15Резервная:​ +
-   1 полубайт ​команда 15, 2 полубайт ​... (можно использовать как пере+
-   дачу других команд,​ т.е. 15-я команда становится ​ п р е ф и к с н о й). +
-   ​Таким образом,​ Ваша подпрограмма должна распознавать номер команды,​ ис+
-полнять ее, исходя из параметров,​ следующих за командой и помещать ​ указа+
-тель данных на следующую команду. Если Вы желаете ​ увеличить ​ музыкальные +
-возможности программы,​а команд (в полубайт можно поместить число от  0 до +
-15) не хватает,​ то необходимо выделить префиксную команду (например,​ 15-ю, +
-так как она резервная)и теперь порядок размещения данных в очереди станет +
-следующим: ​    ​<​Команда>,<​Команда>,​{данное},​{данное},​... +
-               ​<​Команда>,<​Команда>,​{данное},​{данное},​..+
-   ​Кроме аппаратной реализации фонового музыкального сопровождения,​сущест- +
-вует и программная. Вся прелесть аппаратной реализации в том, что уменьше- +
-ние длительности нот происходит в режиме реального времени.Программно мож- +
-но запараллелить многие процессы (в том числе и музыку):​ +
-               ​Process: ​ CALL   ... +
-                         ​CALL ​  ​Music +
-                         ​CALL ​  ... +
-                         ​JR ​    ​Process ​     , +
-но дело в  том, что ​ тактовая частота процесора гораздо выше, чем частота +
-маскируемых ​ прерываний и  без задержки ​ (которая ​ очень ​ часто просто не +
-нужна) казалось бы не обойтись. Н о  в ы х о д  е с т ь! +
-   ​Маскируемые прерывания оставляют след ​ в  области системных переменных,​ +
-и этим можно воспользоваться. Ячейка с адресом 0FC9Eh (Jiffy) хранит этот +
-след. Содержимое Jiffy (2 байта) при каждом новом прерывании ​ увеличивает- +
-ся на единицу,​ а значит,​ момент нового "​тика"​ (это выражение произошло из +
-принципа работы подпрограммы часов компьютера)всегда можно регистрировать. +
-   В Приложении ​   приведена программа обработки музыкальных очередей,​ на- +
-писанная на ассемблере Z80 для компьютера MSX-2.+
 </​code>​ </​code>​
 +Кроме аппаратной реализации фонового музыкального сопровождения,​существует и программная. Вся прелесть аппаратной реализации в том, что уменьшение длительности нот происходит в режиме реального времени.Программно можно запараллелить многие процессы (в том числе и музыку):​
 +<WRAP group>
 +<WRAP half column>
 +<​code>​
 +Process: ​ CALL   ...
 +          CALL   Music
 +          CALL   ...
 +          JR     ​Process
 +</​code>​
 +</​WRAP>​
 +
 +<WRAP half column>
 +,
 +</​WRAP>​
 +</​WRAP>​
 +но дело в том, что тактовая частота процессора гораздо выше, чем частота маскируемых прерываний и без задержки (которая очень часто просто не нужна) казалось бы не обойтись. //Но выход есть//!
 +
 +Маскируемые прерывания оставляют след в области системных переменных,​ и этим можно воспользоваться. Ячейка с адресом 0FC9Eh (Jiffy) хранит этот след. Содержимое Jiffy (2 байта) при каждом новом прерывании увеличивается на единицу,​ а значит,​ момент нового "​тика"​ (это выражение произошло из принципа работы подпрограммы часов компьютера)всегда можно регистрировать.
 +
 +В [[209|Приложении]] приведена программа обработки музыкальных очередей,​ написанная на ассемблере Z80 для компьютера MSX-2.
 +
  
 ---- ----
msx/basic_dialogue_programming_language/107.1674491378.txt.gz · Последние изменения: 2023-01-23 19:29 — GreyWolf