Немига/Звук
< Немига
Этот документ создан для Emuverse и распространяется на условиях лицензии CC-BY-SA-3.0. |
Кодирование мелодии
- Первым должен быть байт октавы и громкости — Двузначное восьмеричное число (см. описание регистра 170030)
- Далее следуют два байта :
- Байт с номером ноты (бит 7=1, то есть коды от 200 до 214)
- Байт с длительностью (в 1/50 долях секунды)
- Далее повторяются два байта, задающие ноту и ее длительность, а при необходимости, перед ними может стоять байт октавы и громкости.
- Мелодия заканчивается байтом, содержащим нули в разрядах 0..4 и 7. Комбинация разрядов 5 и 6 определяют способ завершения мелодии:
- 000 — никаких действий не производится
- 040 — прерывание по вектору 110
- 100 — зацикливание мелодии
- 140 — очистка байта, следующего после индикатора конца мелодии
Управляющие регистры таймера и звука
RgStSnd - 170020 - регистр состояния RgF - 170022 - регистр частоты -- счётчик 1 RgLength - 170024 - регистр длительности -- счётчик 2 RgOn - 170026 - включение звука (обращение) RgOct - 170030 - регистр октавы и громкости RgOff - 170032 - выключение звука (обращение)
170020 Регистр состояния программируемого таймера ┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐ │15│14 13 12│11 10 9│ 8 7 6│ 5 4 3│ 2 1 0│ └──┴──┴──┴──┴──┴──┴─┬┴─┬┴─┬┴─┬┴─┬┴─┬┴─┬┴─┬┴─┬┴─┬┘ Фикс прерывания 2 ─┘ │ │ │ │ │ │ │ │ └─ ?? Фикс прерывания 1 ─┘ │ │ │ │ │ │ └ Режим работы 1-го счётчика Блокировка ЗПР2 ─┘ │ │ │ └──┴─ Режим пуска 1-го счётчика Блокировка ЗПР1 ─┘ │ │ 0 1 блокировка счётчика │ │ 1 0 запуск по CO1 │ │ 1 1 запуск по C1 └──┴─ Режим пуска 2-го счётчика 0 1 блокировка счётчика 1 0 запуск по CO2 1 1 запуск по C2
170030 Регистр октавы и громкости ┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐ │15│14 13 12│11 10 9│ 8 7 6│ 5 4 3│ 2 1 0│ └──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴─┬┴─┬┴─┬┴─┬┴─┬┘ │ │ └──┴──┴─ Октава 1..7 └──┴─ Громкость 0..3
Работа со звуком в ПЗУ Немига 3.03
Точка входа подпрограммы SOUND в начале ПЗУ:
160126: JMP @177754 ; SOUND
Звук нажатия клавиши:
160360: TSTB @#177761 ; Флаг блокировки вызова SOUND 160364: BNE 160402 ; <> 0 => не вызывать повторно 160366: CALL @#160126 ; SOUND 160372: BR 160402 160374: DW 160376 ; Адрес мелодии 160376: DB 011, 214, 001, 000 ; Мелодия -- звук длиной 1/50 сек
Обработка продолжения SOUND в обработчике прерывания HALT:
160602: BIT #010000, @#170006 ; Сигнал Н3? 160610: BEQ 161060 ; Нет => Завершаем обработку прерывания HALT ; Обработка сигнала Н3 160612: MOV R4, -(SP) ; Сохраняем R4 160614: TSTB @#177761 ; Флаг блокировки SOUND 160620: BPL 160746 ; bit7=0 - блокировано => переходим 160622: MOV @#177752, R4 ; Берём адрес продолжения мелодии 160626: INCB @#177760 ; Увеличиваем счётчик?? 160632: CMPB @#177760, 177777(R4) ; Сравниваем с длительностью ноты 160640: BLO 160746 ; пока не кончилась => переходим 160642: TSTB (R4) ; 200 ? 160644: BMI 160742 ; да => переходим 160646: BITB #000037, (R4) ; Есть ещё нота мелодии? 160652: BNE 160736 ; да => переходим 160654: BICB #000200, @#177761 ; Снимаем флаг блокировки SOUND ; Обработка флагов завершения мелодии 160662: BITB #000040, (R4) ; 040 и 140 ? 160666: BNE 160712 ; да => переходим 160670: TSTB (R4) ; 000 ? (никаких действий по окончании мелодии) 160672: BEQ 160746 ; да => переходим 160674: MOV @#177750, @#160710 ; Копируем адрес начала мелодии?? 160702: CALL @#160126 ; SOUND 160706: BR 160746 160710: DW ?? ; Окончание мелодии 160712: BITB #000100, (R4)+ 160716: BNE 160732 160720: MOV (SP)+, R4 160722: CLRB @#170006 ; Переход на прерывание по вектору 110 160726: MOV @#000110, PC ; Очистка байта после мелодии 160732: CLRB (R4) 160734: BR 160746 ; 160736: MOVB (R4)+, @#170030 ; Октава и громкость 160742: CALL @#162560 ; Обработка продолжения мелодии
Подпрограмма SOUND:
162474: MOV R4, -(SP) ; Сохраняем R4 162476: BICB #000200, @#177761 ; Предотвращаем повторный вызов SOUND: bit7=0 162504: CLR @#170024 ; Сброс таймер 2 (длительности) 162510: MOV 000002(SP), R4 ; Откуда вызвали SOUND 162514: MOV 000002(R4), R4 ; Получаем адрес мелодии 162520: TSTB (R4) 162522: BEQ 162554 162524: MOV R4, @#177750 ; Запоминаем адрес начала мелодии 162530: MOV #001516, @#170020 ; Пишем в регистр состояния таймера 162536: MOVB (R4)+, @#170030 ; Октава и громкость 162542: CALL @#162560 ; Обработка продолжения мелодии 162546: BISB #000200, @#177761 ; Возвращаем флаг блокировки SOUND: bit7=1 162554: MOV (SP)+, R4 ; Восстанавливаем R4 162556: RETURN ; 162560: MOV R3, -(SP) ; Сохраняем R3 162562: MOVB (R4)+, R3 162564: BIC #177760, R3 ; Оставляем нижние 4 бита -- 00..17 162570: ASL R3 ; и умножаем на 2 162572: MOV 162624(R3), @#170022 ; Выбираем по R3 слово и пишем в первый счётчик 162600: MOVB (R4)+, @#170024 ; Задаём длительность 162604: CLRB @#177760 ; Очищаем счётчик?? 162610: MOV R4, @#177752 ; Запоминаем адрес продолжения мелодии 162614: TST @#170026 ; Устанавливаем триггер таймера 162620: MOV (SP)+, R3 ; Восстанавливаем R3 162622: RETURN ; Значения задержки первого таймера для нот 162624: DW 000000, 003570, 003414, 003246, 003110, 002754, 002630, 002510 162644: DW 002374, 002264, 002160, 002061, 001764, 000000, 000000, 000000
Переменные:
177750: DW ; Адрес начала мелодии 177752: DW ; Текущий адрес мелодии 177760: DB ; Счётчик 177761: DB ; Флаги