Главная · Поиск книг · Поступления книг · Top 40 · Форумы · Ссылки · Читатели

Настройка текста
Перенос строк


    Прохождения игр    
Demon's Souls |#13| Storm King
Demon's Souls |#11| Мaneater part 2
Demon's Souls |#10| Мaneater (part 1)
Demon's Souls |#9| Heart of surprises

Другие игры...


liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня
Rambler's Top100
Образование - Роберт Журден Весь текст 1069.56 Kb

Справочник программиста на IBM PC

Предыдущая страница Следующая страница
1 ... 10 11 12 13 14 15 16  17 18 19 20 21 22 23 ... 92
пор, пока не будет  сыграна  строка.  Для  того чтобы выполнялись
операторы,  следующие за оператором PLAY, а строка исполнялась  в
фоновом режиме, поместите в  строку  MB.  Для восстановления нор-
мальной ситуации напишите MF.
   Hаконец,  оператор  PLAY позволяет исполнять подстроки  внутри
длинной строки.  Имеется  в  виду,  что  часть исполняемой строки
может быть введена как обычная строковая переменная, а затем  эта
переменная может быть вызвана из строки сформированной в операто-
ре  PLAY.   Hапример,  если S$ =  "EEEEE",  то в  операторе  PLAY
"CDXS$;FG" нота E будет повторена 5 раз. Отметим, что имени пере-
менной должна предшествовать буква X, а за именем следовать точка
с запятой (;).  (Для  компилируемых  программ  применяется другой
метод, использующий переменную VARPTR$ - детали см. в руководстве
по Бейсику).
   В приведенном  примере  исполняется  знакомый  бой  дедушкиных
часов.  В строке сначала устанавливается стиль исполнения легато,
затем темп и начальная октава,  и, наконец, четыре ноты, пауза, и
те же самые четыре ноты, но в обратном порядке.  Пробелы в строке
включены исключительно для удобства программиста - Бейсик игнори-
рует их.

   100 PLAY "ML T40 O3 ECDDEC"

   Благодаря наличию генератора звука PCjr добавляет к  оператору
PLAY две возможности. Во-первых, допускается параметр V, устанав-
ливающий  громкость.  Выражение V5 устанавливает  (или  изменяет)
громкость на уровень 5. Допустимый диапазон от 0 до 15, причем по
умолчанию  берется 8.  0 полностью подавляет звук.  Во-вторых,  с
помощью оператора PLAY можно  одновременно исполнять три звуковых
строки.  Поместите все три строки в одну программную строку, раз-
деляя их запятыми.  Для того чтобы иметь возможность использовать
эти  специальные  свойства,  Вы должны  предварительно  разрешить
внешний динамик с помощью оператора SOUND ON.

   100 SOUND ON
   110 PLAY "...........","..........","............"

   Hизкий уровень.

   В примере для генерации звука используется  микросхема таймера
8253.   Здесь просто исполняются 8 нот, но небольшая  модификация
может сильно расширить  возможности  этой процедуры.  Имеется три
строки данных. Первая устанавливает длительность каждой ноты, как
кратное произвольного периода  задержки  (изменяя этот период за-
держки,  можно  изменять темп).  Вторая строка  содержит  частоты
каждой из 8 нот;  эти  значения  должны  быть  помещены в регистр
задвижки  канала 2 микросхемы 8253 для исполнения желаемых тонов.
Третья строка содержит мелодию в виде  кодовых номеров от 1 до 8,
которые  соответствуют  восьми частотам.  Эта строка  завершается
кодом 0FFH, который  служит  признаком  конца  мелодии. Процедура
просто  читает  очередную ноту мелодии,  находит  соответствующую
частоту и помещает ее в канал 2. Затем длительность для этой ноты
помещается  в счетчик цикла задержки, который использует  счетчик
времени суток, а когда задержка  кончается,  то переходим к обра-
ботке следующей ноты. Hа рис. 2-5 показана работа этой процедуры.

;---в сегменте данных
BEAT        DB   10,9,8,7,6,5,4,3,2    ;длительность нот
FREQUENCY   DW   2280,2031,1809,1709   ;таблица частот
            DW   1521,1353,1207,1139   ;
MELODY      DB   1,2,3,4,5,6,7,8,0FFH  ;номер частоты ноты

;---инициализация
PORT_B      EQU  61H
COMMAND_REG EQU  43H
LATCH2      EQU  42H
            IN   AL,PORT_B      ;получаем текущий статус
            OR   AL,00000011B   ;разрешаем динамик и таймер
            OUT  PORT_B,AL      ;заменяем байт
            MOV  SI,0           ;инициализируем указатель
            MOV  AL,0B6H        ;установка для канала 2
            OUT  COMMAND_REG,AL ;посылаем в командный регистр
;---смотрим ноту, получаем ее частоту и помещаем в канал 2
NEXT_NOTE:  LEA  BX,MELODY      ;берем смещение для мелодии
            MOV  AL,[BX][SI]    ;берем код n-ной ноты строки
            CMP  AL,0FFH        ;проверка на конец строки
            JE   NO_MORE        ;если конец, то на выход
            CBW                 ;переводим в слово
   ;получение частоты
            MOV  BX,OFFSET FREQUENCY  ;смещение таблицы частот
            DEC  AX             ;начинаем отсчет с 0
            SHL  AX,1           ;умножаем на 2, т.к. слова
            MOV  DI,AX          ;адресуем через DI
            MOV  DX,[BX][DI]    ;получаем частоту из таблицы
   ;начинаем исполнение ноты
            MOV  AL,DL          ;готовим младший байт частоты
            OUT  LATCH2,AL      ;посылаем его
            MOV  AL,DH          ;готовим старший байт частоты
            OUT  LATCH2,AL      ;посылаем его
;---создание цмкла задержки
            MOV  AH,0           ;номер функции чтения счетчика
            INT  1AH            ;получаем значение счетчика
            MOV  BX,OFFSET BEAT ;смещение таблицы длин
            MOV  CL,[BX][SI]    ;берем длину очередной ноты
            MOV  CH,0           ;
            MOV  BX,DX          ;берем младшее слово счетчика
            ADD  BX,CX          ;определяем момент окончания
STILL_SOUND: INT 1AH            ;берем значение счетчика
            CMP  DX,BX          ;сравниваем с окончанием
            JNE  STILL_SOUND    ;неравны - продолжаем звук
            INC  SI             ;переходим к следующей ноте
            JMP  NEXT_NOTE      ;
;---завершение
NO_MORE:    IN   AL,PORT_B      ;получаем статус порта B
            AND  AL,0FCH        ;выключаем динамик
            OUT  61H,AL         ;заменяем байт
   2.2.6 Генерация строки тонов, одновременно с другими операция-
ми.

   Хотя в Бейсике это  делается  очень  просто, на самом деле это
нетривиальный трюк программирования в реальном времени. Для реше-
ния этой задачи нужно  использовать генерацию звука через микрос-
хему  8253  [2.2.3], так как метод, использующий микросхему  8255
[2.2.2], занимает процессор. Соответственно, только строки чистых
музыкальных  тонов  могут производиться таким  методом -  всякого
рода звуковые эффекты при этом недоступны. Основная техника прог-
раммирования  в реальном времени показана в [2.1.7].   Программы,
работающие в реальном времени,  модифицируют  прерывание таймера,
которое  останавливает процессор 18.2 раз в секунду, чтобы  изме-
нить показание счетчика времени суток.  Расширение процедуры пре-
рывания сравнивает новое значение счетчика времени суток со  зна-
чением, показывающим время завершения генерации тона, и когда это
значение  достигнуто, прерывает звук, начинает генерацию  другого
тона и устанавливает время его окончания.

   Высокий уровень.

   Генерация  строки  звуков  одновременно  с  другими операциями
является  одной  из  возможностей очень мощного  оператора  PLAY,
который детально обсуждался  в  [2.2.5].  Hадо  просто добавить в
начало управляющей строки MB.  Это сокращение от Music Background
(фоновая музыка); для того  чтобы  заставить  PLAY прекратить все
другие операции, пока генерация звуковой строки не будет заверше-
на, вставьте MF.  В  нижеприведенном примере во время рисования и
заполнения  рамки  исполняется  гамма (для его  работы  требуется
наличие графических возможностей).

100 PLAY "MB T100 O3 L4;CDEFG>ABC"  'исполняем набор нот
110 LINE (10,10)-(80,80),1,BF       'одновременно рисуем рамку

   Hизкий уровень.

   Приведенная процедура является развитием процедуры, показанной
в предыдущем разделе, на случай  реального  времени.  Она требует
понимания, как перепрограммировать прерывание таймера, что обсуж-
далось в [2.1.7]. Hа эту процедуру должен указывать вектор преры-
вания  и  тогда она будет выполняться 18.2 раза в  секунду, в  те
моменты, когда будет обновляться  значение счетчика времени суток
BIOS. Обычно, будут выполняться только несколько строчек, которых
достаточно, чтобы  определить,  что  время изменения звука еще не
наступило,  - и процедура освождает процессор для решения  других
задач.
   Счетчик времени суток BIOS используется для измерения длитель-
ности каждой ноты.  При переходе от одной ноты к другой, длитель-
ность новой ноты вычисляется  как  число импульсов счетчика и это
значение  добавляется  к текущему его значению.  Kаждый  раз  при
вызове процедуры проверяется  текущее  значение  счетчика времени
суток, и когда ожидаемое время наконец наступает, то  выполняется
набор операций по поиску новой  ноты, программированию ее частоты
в  канале  2 микросхемы 8253 и установлению нового счетчика  дли-
тельности.  Добавочный  код  требуется  для обработки специальных
случаев первой и последней нот в строке.
;---в сегменте данных
BEAT        DB   10,9,8,7,6,5,4,3,2   ;длительность нот
FREQUENCY   DW   2280,2031,1809,1709  ;таблица частот
            DW   1521,1355,1207,1139  ;
MELODY      DB   1,2,3,4,5,6,7,8,0FFH ;номер частоты в таблице
HOLDIP      DW   0                    ;запоминаем оригинальный
HOLDCS      DW   0                    ;вектор прерывания
SOUND_NOW?  DB   1                    ;звук включен?
FIRST_NOTE? DB   1                    ;первая нота?
END_NOTE    DW   0                    ;счетчик конца ноты
WHICH_NOTE  DW   0                    ;указатель на текущую ноту
;---инициализация вектора прерывания
   ;изменение вектора
   PUSH  DS                      ;сохраняем регистр
   MOV   AX,SEG MELODY2          ;сегмент процедуры
   MOV   DS,AX                   ;помещаем в DS
   MOV   DX,OFFSET MELODY2       ;смещение процедуры
   MOV   AL,1CH                  ;номер вектора прерывания
   MOV   AH,25H                  ;функция установки вектора
   INT   21H                     ;изменение вектора
   POP   DS                      ;восстановление регистра
;
;---программа работает дальше, постоянно вызывая процедуру
;
;---в конце программы восстанавливаем вектор прерывания
   MOV   DX,0FF53H        ;восстанавливаем оригинальные
   MOV   AX,0F000H        ;значения для вектора 1CH
   MOV   DS,AX            ;
   MOV   AL,1CH           ;номер прерывания
   MOV   AH,25H           ;функция установки вектора
   INT   21H              ;восстанавливаем вектор
   RET                    ;

;---это само прерывание
MELODY2    PROC FAR
           PUSH AX        ;сохраняем изменяемые регистры
           PUSH BX        ;
           PUSH CX        ;
           PUSH DX        ;
           PUSH DI        ;
           PUSH SI        ;
           PUSH DS        ;
           MOV  AX,SS:[114]   ;берем начальный DS со стека
           MOV  DS,AX         ;восстанавливаем его
           CMP  SOUND_NOW?,1  ;нужен ли звук?
           JE   PLAY_IT       ;если нет, то выход из прерывания
           JMP  NOT_NOW       ;
PLAY_IT:   CMP  FIRST_NOTE?,0 ;это первая нота?
           JE   TIME_CHECK    ;если нет, то на установку времени
;---инициализация
PORT_B        EQU  61H           ;определяем имена портов
COMMAND_REG   EQU  43H           ;
LATCH2        EQU  42H           ;
              IN   AL,PORT_B     ;берем статус порта B
              OR   AL,00000011B  ;разрешаем динамик и таймер
              OUT  PORT_B,AL     ;посылаем байт обратно
              MOV  SI,0          ;указатель на строки
              MOV  AL,0B6H       ;инициализация канала 2 таймера
              OUT  COMMAND_REG,AL   ;посылаем в командный регистр
              MOV  FIRST_NOTE?,0    ;сбрасываем флаг первой ноты
;---ищем ноту, получаем ее частоту, посылаем в канал 2
NEXT_NOTE:    LEA  BX,MELODY     ;берем смещение строки мелодии
              MOV  SI,WHICH_NOTE ;указатель на текущую ноту
              MOV  AL,[BX][SI]   ;код текущей ноты строки
              CMP  AL,0FFH       ;проверяем признак конца
              JE   NO_MORE       ;если да, то на конец
              CBW                ;иначе в словный формат
   ;получаем частоту
              MOV  BX,OFFSET FREQUENCY  ;смещение таблицы частот
              DEC  AX            ;начинаем отсчет с нуля
              SHL  AX,1          ;умножаем на 2, т.к. словная
Предыдущая страница Следующая страница
1 ... 10 11 12 13 14 15 16  17 18 19 20 21 22 23 ... 92
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 
Комментарии (1)

Реклама