Страница 19 из 19
2.2.9 Одновременная генерация разных звуков. Только микросхема генератора звука, имеющаяся в PCjr, позво- ляет одновременно генерировать разные звуки (см. обсуждение в [2.2.1]). Однако ассемблер позволяет объединить два способа гене- рации звука, что создает имитацию одновременной генерации двух разных звуков. Интерференция этих двух сигналов приводит к слож- ной форме звуковой волны. Каждый из двух звуков имеет меньшую громкость, поэтому в результате получается скорее жужжание, чем два разных голоса. Этот прием реально полезен только для создания звуковых эффектов.
Низкий уровень. Надо просто объединить два метода генерации звука, показанные в [2.2.2] и [2.2.3]. Начните звук через канал 2 микросхемы тайме- ра. Затем модулируйте выход динамика, за счет бита 1 порта B микросхемы интерфейса с периферией. Второе действие определяет продолжительность звука. Не забудьте выключить микросхему таймера при завершении.
;---начинаем генерацию звука через канал 2 таймера IN AL,61H ;получаем байт из порта B OR AL,3 ;устанавливаем младшие два байта OUT 61H,AL ;посылаем байт обратно MOV AL,10110110B ;цепочка для командного регистра 8253 OUT 43H,AL ;посылаем в регистр MOV AX,600H ;счетчик для канала 2 OUT 42H,AL ;посылаем младший байт MOV AL,AH ;готовим старший байт OUT 42H,AL ;посылаем старший байт ;---генерируем вторую частоту микросхемой 8255 NUMBER_CYCLES EQU 9000 ;число переключений FREQUENCY EQU 150 ;задержка для половины цикла CLI ;запрет прерываний MOV DX,NUMBER_CYCLES ;DX считает длину тона IN AL,61H ;получаем статус порта AND AL,11111111B ;отключаем динамик от таймера NEXT_CYCLE: OR AL,00000010B ;включаем динамик OUT 61H,AL ;посылаем назад в порт MOV CX,FREQUENCY ;задержка на 1/2 цикла FIRST_HALF: LOOP FIRST_HALF ; AND AL,11111101B ;выключаем динамик OUT 61H,AL ;посылаем команду в порт MOV CX,FREQUENCY ;задержка на 1/2 цикла SECOND_HALF: LOOP SECOND_HALF ; DEC DX ;меняем счетчик циклов JNZ NEXT_CYCLE ;если 0, то пора кончать STI ;разрешаем прерывания ;---выключение канала 2 микросхемы таймера IN AL,61H ;получаем статус порта AND AL,11111100B ;сбрасываем 2 младших бита OUT 61H,AL ;посылаем байт обратно
|