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

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


msx:basic_dialogue_programming_language:107

Различия

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

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

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
msx:basic_dialogue_programming_language:107 [2023-01-24 15:05]
GreyWolf [1.7. Программирование звуковых эффектов]
msx:basic_dialogue_programming_language:107 [2023-02-18 18:12] (текущий)
GreyWolf
Строка 6: Строка 6:
 FIXME FIXME
  
-Мы уже говорили о возможностях работы с Программируемым Звуковым Генератором — PSG. Здесь мы расскажем Вам о работе с PSG  при программировании в машинных кодах.+Мы уже говорили о возможностях работы с Программируемым Звуковым Генератором — PSG. Здесь мы расскажем Вам о работе с PSG при программировании в машинных кодах.
  
 Вначале кратко //​повторим//​ основные сведения. Вначале кратко //​повторим//​ основные сведения.
Строка 18: Строка 18:
 |  4  |Младший байт частоты канала C| |  4  |Младший байт частоты канала C|
 |  5  |Старший байт частоты канала C| |  5  |Старший байт частоты канала C|
-|  6  |Частота шума ​ |+|  6  |Частота шума|
 |  7  |Выбор звучания каналов| |  7  |Выбор звучания каналов|
 |  8  |Громкость канала A| |  8  |Громкость канала A|
Строка 27: Строка 27:
 |  13  |Указатель формы волны| |  13  |Указатель формы волны|
  
-Звуки бывают двух типов, которые мы назовем "​звук"​ и "​шум"​. За сочетание звучания "​звука"​ и "​шума"​ отвечает 7-й регистр PSG:+Звуки бывают двух типов, которые мы назовем "​звук"​ и "​шум"​. За сочетание звучания "​звука"​ и "​шума"​ отвечает 7й регистр PSG:
  
 <​code>​ <​code>​
Строка 58: Строка 58:
 |  A2h  |  Последнее число, записанное в PSG  | |  A2h  |  Последнее число, записанное в PSG  |
  
-Существует два способа записи чисел в PSG средствами языка ​MSX-BASIC:+Существует два способа записи чисел в PSG средствами языка ​[[msx:​basic:​|]]:
   * α) <​code>​SOUND reg, data</​code>​   * α) <​code>​SOUND reg, data</​code>​
   * β) <​code>​OUT &​HA0,​reg:​OUT &​HA1,​data</​code>​   * β) <​code>​OUT &​HA0,​reg:​OUT &​HA1,​data</​code>​
  
-__//​Пример 1.//__  Программа в машинных кодах, записывающая число ​ 254  в звуко-генератор (в регистр 0).+{{anchor:​e1070-01}} ​__//​Пример 1//__Программа в машинных кодах, записывающая число 254 в звукогенератор (в регистр 0).\\ {{.examples:​1070-01.bas|}} \\ [[+tab|wmsxbpge>​1070-01.bas]]
 <​code>​ <​code>​
 10 CLEAR 200,&​HF000:​DEFUSR=&​HF000 10 CLEAR 200,&​HF000:​DEFUSR=&​HF000
Строка 78: Строка 78:
  
 Следующая таблица поможет Вам при моделировании оператора ''​PLAY''​ в машинных кодах (данные приведены для канала A): Следующая таблица поможет Вам при моделировании оператора ''​PLAY''​ в машинных кодах (данные приведены для канала A):
 +
 +|<30% 25% 15% 15% 15%>|
 ^  Октава ​ ^  Нота ^  Рег.0 ​ ^  Рег.1 ​ ^ ^  Октава ​ ^  Нота ^  Рег.0 ​ ^  Рег.1 ​ ^
-|  O1 \\ (контр-октава) ​ |C|  93|  13  |+|  O1 \\ (контроктава) ​ |C|  93|  13  |
 |:::​|C#​| ​ 156|  12  | |:::​|C#​| ​ 156|  12  |
 |::: |D|  231|  11  | |::: |D|  231|  11  |
Строка 91: Строка 93:
 |:::​|A#​| ​ 128|  7  | |:::​|A#​| ​ 128|  7  |
 |:::​|B| ​ 20|  7  | |:::​|B| ​ 20|  7  |
-|  O2 \\ (большая) ​ | C  |  175|  6  |+|  O2 \\ (большая) ​ |C|  175|  6  |
 |:::| C# |  78|  6  | |:::| C# |  78|  6  |
 |:::| D  |  244|  5  | |:::| D  |  244|  5  |
Строка 103: Строка 105:
 |:::| A# |  192|  3  | |:::| A# |  192|  3  |
 |:::| B  |  138|  3  | |:::| B  |  138|  3  |
-|  O3 \\ (малая) ​ | C  |  87 |  3  |+|  O3 \\ (малая) ​ | C  |  87|  3  |
 |:::| C# |  39|  3  | |:::| C# |  39|  3  |
 |:::| D  |  250|  2  | |:::| D  |  250|  2  |
Строка 115: Строка 117:
 |:::| A# |  224|  1  | |:::| A# |  224|  1  |
 |:::| B  |  197|  1  | |:::| B  |  197|  1  |
-|  O4 \\ (первая) ​ | C  | 172 |  1  |+|  O4 \\ (первая) ​ | C  |  172|  1  |
 |:::| C# |  148|  1  | |:::| C# |  148|  1  |
 |:::| D  |  125|  1  | |:::| D  |  125|  1  |
Строка 127: Строка 129:
 |:::| A# |  240|  0  | |:::| A# |  240|  0  |
 |:::| B  |  227|  0  | |:::| B  |  227|  0  |
-|  O5 (вторая) ​ | C  | 214 |  0  |+|  O5 (вторая) ​ | C  |  214|  0  |
 |:::| C# |  202|  0  | |:::| C# |  202|  0  |
 |:::| D  |  190|  0  | |:::| D  |  190|  0  |
Строка 139: Строка 141:
 |:::| A# |  120|  0  | |:::| A# |  120|  0  |
 |:::| B  |  113|  0  | |:::| B  |  113|  0  |
-|  O6 \\ (третья) ​ | C  | 107 |  0  |+|  O6 \\ (третья) ​ | C  |  107|  0  |
 |:::| C# |  101|  0  | |:::| C# |  101|  0  |
 |:::| D  |  95|  0  | |:::| D  |  95|  0  |
Строка 151: Строка 153:
 |:::| A# |  60|  0  | |:::| A# |  60|  0  |
 |:::| B  |  57|  0  | |:::| B  |  57|  0  |
-|  O7 \\ (четвёртая) ​ | C  |  53 |  0  |+|  O7 \\ (четвёртая) ​ | C  |  53|  0  |
 |:::| C# |  50|  0  | |:::| C# |  50|  0  |
 |:::| D  |  48|  0  | |:::| D  |  48|  0  |
Строка 163: Строка 165:
 |:::| A# |  30|  0  | |:::| A# |  30|  0  |
 |:::| B  |  28|  0  | |:::| B  |  28|  0  |
-|  O8 \\ (пятая) ​ | C  |  27 |  0  |+|  O8 \\ (пятая) ​ | C  |  27|  0  |
 |:::| C# |  25|  0  | |:::| C# |  25|  0  |
 |:::| D  |  24|  0  | |:::| D  |  24|  0  |
Строка 175: Строка 177:
 |:::| A# |  15|  0  | |:::| A# |  15|  0  |
 |:::| B  |  14|  0  | |:::| B  |  14|  0  |
-|(шестая)| ​ —  |  13|0|+|(шестая)| ​ —  |  13|   |
  
-__//​Пример 2.//__ Программа,​ позволяющая прочесть данные ​ из звукогенератора и проверить приведённую таблицу.+{{anchor:​e1070-02}} ​__//​Пример 2//__Программа,​ позволяющая прочесть данные из звукогенератора и проверить приведённую таблицу.\\ {{.examples:​1070-02.bas|}} \\ [[+tab|wmsxbpge>​1070-02.bas]]
 <​code>​ <​code>​
 10 CLEAR 200,&​HF000:​DEFUSR=&​HF000 10 CLEAR 200,&​HF000:​DEFUSR=&​HF000
Строка 189: Строка 191:
 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>​ </​code>​
  
Строка 196: Строка 198:
 (Данный раздел написан А.Н.Никитиным) (Данный раздел написан А.Н.Никитиным)
  
-Существует несколько вариантов реализации фонового ​ сопровождения ​ программы. Вспомним один из рутинных вариантов воплощения ​ фонового музыкального сопровождения. Зная, что длительность нот намного превышает время выполнения процессором арифметических операций,​ можно установить ​ соответствие между музыкальной длительностью и определённым количеством ​ арифметических операций,​ выполняемых процессором. Далее остаётся последовательно вставлять музыкальные фрагменты (их длина, разумеется,​ должна быть ограничена настолько,​чтобы программа не "​зависала"​!) между операторами основной программы. Ясно, что такой способ вызывает ​ массу ​ неудобств:​ значительно усложняется редактирование программы,​ программирование ​ требует ​ огромных затрат времени и труда, об универсальности программы не может быть и речи.+Существует несколько вариантов реализации фонового сопровождения программы. Вспомним один из рутинных вариантов воплощения фонового музыкального сопровождения. Зная, что длительность нот намного превышает время выполнения процессором арифметических операций,​ можно установить соответствие между музыкальной длительностью и определённым количеством арифметических операций,​ выполняемых процессором. Далее остаётся последовательно вставлять музыкальные фрагменты (их длина, разумеется,​ должна быть ограничена настолько,​чтобы программа не "​зависала"​!) между операторами основной программы. Ясно, что такой способ вызывает массу неудобств:​ значительно усложняется редактирование программы,​ программирование требует огромных затрат времени и труда, об универсальности программы не может быть и речи.
  
 Предлагаемый нами алгоритм реализации фонового музыкального сопровождения полностью //​исключает//​ перечисленные неудобства! Предлагаемый нами алгоритм реализации фонового музыкального сопровождения полностью //​исключает//​ перечисленные неудобства!
  
-Расскажем Вам идею алгоритма. Во время работы процессор совершает ​ маскируемые прерывания частотой 5О Гц и опрашивает область ловушек (hooks),а точнее происходят обращения (CALL ...) по адресам FD9Ah, FD9Fh. Напомним Вам, что эти прерывания разрешаются командой ассемблера EI, а запрещаются командой DI. Начальный адрес Таблицы ловушек ​&hFD9A. По этому адресу системной области хранится подпрограмма перехода на программу сетевого обмена у компьютеров серии MSX-2 и число &​HC9(машинный код команды RET) у компьютеров серии MSX-1, поэтому при обращении к данной ловушке либо из  подпрограммы обработки прерываний (которая расположена по адресу 0038h), либо из Вашей программы означает мгновенный возврат в основную программу (если MSX-2 не ведёт "​сетевой диалог"​).+Расскажем Вам идею алгоритма. Во время работы процессор совершает маскируемые прерывания частотой 5О Гц и опрашивает область ловушек (hooks),а точнее происходят обращения (CALL ...) по адресам FD9Ah, FD9Fh. Напомним Вам, что эти прерывания разрешаются командой ассемблера EI, а запрещаются командой DI. Начальный адрес Таблицы ловушек ​— &hFD9A. По этому адресу системной области хранится подпрограмма перехода на программу сетевого обмена у компьютеров серии MSX-2 и число &​HC9(машинный код команды RET) у компьютеров серии MSX-1, поэтому при обращении к данной ловушке либо из подпрограммы обработки прерываний (которая расположена по адресу 0038h), либо из Вашей программы означает мгновенный возврат в основную программу (если MSX-2 не ведёт "​сетевой диалог"​).
  
 Если по адресу FD9Ah "​положить"​ подпрограмму:​ Если по адресу FD9Ah "​положить"​ подпрограмму:​
Строка 217: Строка 219:
 </​WRAP>​ </​WRAP>​
 </​WRAP>​ </​WRAP>​
-где ​ N_slot — это номер слота, в котором будет расположена Ваша программа,​ а  Adres — это адрес Вашей подпрограммы обработки прерываний,​ то 50 раз в секунду управление будет передаваться Вашей подпрограмме,​ в которой можно управлять музыкой,​ печатью,​ графикой или опрашивать клавиатуру.+где N_slot — это номер слота, в котором будет расположена Ваша программа,​ а Adres — это адрес Вашей подпрограммы обработки прерываний,​ то 50 раз в секунду управление будет передаваться Вашей подпрограмме,​ в которой можно управлять музыкой,​ печатью,​ графикой или опрашивать клавиатуру.
  
 Вообще говоря,​число 50 не очень удобно для точного отсчёта музыкальной длительности (так как 50 не делится на 8, 16, 32; в этом смысле идеальным было бы число 64), но при сравнении длительностей между собой (а не с метрономом) искажение звука практически незаметно. Вообще говоря,​число 50 не очень удобно для точного отсчёта музыкальной длительности (так как 50 не делится на 8, 16, 32; в этом смысле идеальным было бы число 64), но при сравнении длительностей между собой (а не с метрономом) искажение звука практически незаметно.
  
-Структура музыкальной подпрограммы довольно проста:​ она должна ​ обрабатывать данные и управлять музыкальными очередями. Вся сложность состоит в том, чтобы построить такую структуру музыкальных данных,​ которая ​ удовлетворяла бы следующим требованиям:​ объем данных должен быть минимальным,​ возможности управления музыкальным генератором должны быть ​ большими,​ должны присутствовать элементы программирования (циклы,​переходы ​ и т.д.), должно выполняться большинство музыкальных выражений (Legato, Staccato и т.д.).+Структура музыкальной подпрограммы довольно проста:​ она должна обрабатывать данные и управлять музыкальными очередями. Вся сложность состоит в том, чтобы построить такую структуру музыкальных данных,​ которая удовлетворяла бы следующим требованиям:​ объем данных должен быть минимальным,​ возможности управления музыкальным генератором должны быть большими,​ должны присутствовать элементы программирования (циклы,​переходы и т.д.), должно выполняться большинство музыкальных выражений (Legato, Staccato и т.д.).
  
-В предложенном ниже описании структуры музыкальных данных,​ мы  постарались удовлетворить лишь части названных требований.Структура данных очень напоминает стандарт MIDI–интерфейса(Musical Instrument Digital Interface).+В предложенном ниже описании структуры музыкальных данных,​ мы постарались удовлетворить лишь части названных требований.Структура данных очень напоминает стандарт MIDI–интерфейса(Musical Instrument Digital Interface).
  
 Порядок размещения данных в очереди следующий:​ Порядок размещения данных в очереди следующий:​
Строка 235: Строка 237:
 ^  //​Команда// ​ ^  Описание ​ ^ ^  //​Команда// ​ ^  Описание ​ ^
 |0|Установка частоты (высоты) звучания:​ \\ 1 полубайт — команда 00 ; 2 полубайт — номер ноты 1÷12.| |0|Установка частоты (высоты) звучания:​ \\ 1 полубайт — команда 00 ; 2 полубайт — номер ноты 1÷12.|
-|1|Микширование (регистр 7 PSG,по умолчанию ​&​hb10111000):​ \\ 1 полубайт ​команда 01 , 2 полубайт ​формальный , следующий байт ​байт состояния (структура аналогична структуре данных,​ находящихся в регистре 7): <​code>​+|1|Микширование (регистр 7 PSG,по умолчанию ​— &​hb10111000):​ \\ 1 полубайт ​— команда 01 , 2 полубайт ​— формальный , следующий байт ​— байт состояния (структура аналогична структуре данных,​ находящихся в регистре 7): <​code>​
 &b10 ∗∗∗ ∗∗∗ &b10 ∗∗∗ ∗∗∗
      ​▲▲▲ ▲▲▲      ​▲▲▲ ▲▲▲
Строка 243: Строка 245:
 </​code>​| </​code>​|
 |2|Установка темпа воспроизведения (по умолчанию — 1): \\ 1 полубайт — команда 02 ; 2 полубайт — данное (1÷2).| |2|Установка темпа воспроизведения (по умолчанию — 1): \\ 1 полубайт — команда 02 ; 2 полубайт — данное (1÷2).|
-|3|Установка амплитуды звучания (по умолчанию — 8): \\ 1 полубайт — команда 03, 2 полубайт — данное ​ (0÷15) (амплитуда = данное + 1).|+|3|Установка амплитуды звучания (по умолчанию — 8): \\ 1 полубайт — команда 03, 2 полубайт — данное (0÷15) (амплитуда = данное + 1).|
 |4|Установка частоты шума (по умолчанию — 20): \\ 1 полубайт — команда 04, 2 полубайт — данное (1÷15, частота = данное·2).| |4|Установка частоты шума (по умолчанию — 20): \\ 1 полубайт — команда 04, 2 полубайт — данное (1÷15, частота = данное·2).|
 |5|Установка формы волны (пакета):​ \\ 1 полубайт — команда 05 , 2 полубайт — данное (1÷15).| |5|Установка формы волны (пакета):​ \\ 1 полубайт — команда 05 , 2 полубайт — данное (1÷15).|
-|6|Установка значения для 11 регистра PSG(по умолчанию-100) \\ 1 полубайт — команда 06, 2 полубайт — данное (0÷15, значение = данное · 10).| +|6|Установка значения для 11 регистра PSG(по умолчанию ​— 100) \\ 1 полубайт — команда 06, 2 полубайт — данное (0÷15, значение = данное · 10).| 
-|7|Установка значения для 12 регистра PSG(по умолчанию-10): \\ 1 полубайт — команда 07, 2 полубайт ​данное (0÷15, значение=данное·2).|+|7|Установка значения для 12 регистра PSG(по умолчанию ​— 10): \\ 1 полубайт — команда 07, 2 полубайт ​— данное (0÷15, значение=данное·2).|
 |8|Установка текущей длительности звучания:​ \\ 1 полубайт — команда 08, \\ 2 полубайт — данное (1÷15), где <​WRAP>​ |8|Установка текущей длительности звучания:​ \\ 1 полубайт — команда 08, \\ 2 полубайт — данное (1÷15), где <​WRAP>​
-  * 1 — целая с точкой, ​  +  * 1 — целая с точкой,​ 
-  * 2 — целая, ​+  * 2 — целая,
   * 3 — половинная с точкой,​   * 3 — половинная с точкой,​
-  * 4 — половинная,​  +  * 4 — половинная,​ 
-  * 5 — четвертная с точкой, ​+  * 5 — четвертная с точкой,​
   * 6 — четвертная,​   * 6 — четвертная,​
-  * 7 — восьмая с точкой,​  +  * 7 — восьмая с точкой,​ 
-  * 8 — восьмая, ​+  * 8 — восьмая,​
   * 9 — шестнадцатая с точкой,​   * 9 — шестнадцатая с точкой,​
   * 10 — шестнадцатая,​   * 10 — шестнадцатая,​
   * 11 — тридцатьвторая с точкой,​   * 11 — тридцатьвторая с точкой,​
-  * 12 — тридцатьвторая. ​+  * 12 — тридцатьвторая.
 </​WRAP>​| </​WRAP>​|
 |9|Пауза:​ \\ 1 полубайт — команда 09, 2 полубайт — формальный.| |9|Пауза:​ \\ 1 полубайт — команда 09, 2 полубайт — формальный.|
Строка 270: Строка 272:
 |15|Резервная:​ \\ 1 полубайт — команда 15, 2 полубайт — ... (можно использовать как передачу других команд,​ т.е. 15–я команда становится //​префиксной//​).| |15|Резервная:​ \\ 1 полубайт — команда 15, 2 полубайт — ... (можно использовать как передачу других команд,​ т.е. 15–я команда становится //​префиксной//​).|
  
-Таким образом,​ Ваша подпрограмма должна распознавать номер команды,​ исполнять её, исходя из параметров,​ следующих за командой и помещать ​ указатель данных на следующую команду. Если Вы желаете ​ увеличить ​ музыкальные возможности программы,​а команд (в полубайт можно поместить число от 0 до 15) не хватает,​ то необходимо выделить префиксную команду (например,​ 15-ю, так как она резервная)и теперь порядок размещения данных в очереди станет следующим:​+Таким образом,​ Ваша подпрограмма должна распознавать номер команды,​ исполнять её, исходя из параметров,​ следующих за командой и помещать указатель данных на следующую команду. Если Вы желаете увеличить музыкальные возможности программы,​а команд (в полубайт можно поместить число от 0 до 15) не хватает,​ то необходимо выделить префиксную команду (например,​ 15ю, так как она резервная)и теперь порядок размещения данных в очереди станет следующим:​
 <​code>​ <​code>​
 <​Команда>,<​Команда>,​{данное},​{данное},​... <​Команда>,<​Команда>,​{данное},​{данное},​...
Строка 290: Строка 292:
 </​WRAP>​ </​WRAP>​
 </​WRAP>​ </​WRAP>​
-но дело в  том, что ​ тактовая частота процессора гораздо выше, чем частота маскируемых ​ прерываний и  без задержки ​ (которая ​ очень ​ часто просто не нужна) казалось бы не обойтись. //Но выход есть//!+но дело в том, что тактовая частота процессора гораздо выше, чем частота маскируемых прерываний и без задержки (которая очень часто просто не нужна) казалось бы не обойтись. //Но выход есть//!
  
-Маскируемые прерывания оставляют след ​ в  области системных переменных,​ и этим можно воспользоваться. Ячейка с адресом 0FC9Eh (Jiffy) хранит этот след. Содержимое Jiffy (2 байта) при каждом новом прерывании ​ увеличивается на единицу,​ а значит,​ момент нового "​тика"​ (это выражение произошло из принципа работы подпрограммы часов компьютера)всегда можно регистрировать.+Маскируемые прерывания оставляют след в области системных переменных,​ и этим можно воспользоваться. Ячейка с адресом 0FC9Eh (Jiffy) хранит этот след. Содержимое Jiffy (2 байта) при каждом новом прерывании увеличивается на единицу,​ а значит,​ момент нового "​тика"​ (это выражение произошло из принципа работы подпрограммы часов компьютера)всегда можно регистрировать.
  
 В [[209|Приложении]] приведена программа обработки музыкальных очередей,​ написанная на ассемблере Z80 для компьютера MSX-2. В [[209|Приложении]] приведена программа обработки музыкальных очередей,​ написанная на ассемблере Z80 для компьютера MSX-2.
msx/basic_dialogue_programming_language/107.1674561951.txt.gz · Последние изменения: 2023-01-24 15:05 — GreyWolf