Справочник программиста на персональном компьютере фирмы IBM. Таймеры и звук - Генерация случайных чисел с помощью микросхемы таймера

ОГЛАВЛЕНИЕ

     2.1.8 Генерация случайных чисел с помощью микросхемы таймера.


   Для  генерации  последовательности случайных  чисел  требуются
сложные математические манипуляции. Но иногда программе в опреде-
ленный момент требуется только одно случайное число.  В этом слу-
чае случайное число может быть получено  просто чтением из канала
микросхемы таймера.  Бейсик использует это число в качестве ядра,
по которому генерируется случайная  последовательность.  Конечно,
Вы не можете использовать ряд последовательно  считанных значений
в  качестве  случайной последовательности, так как сами  по  себе
интервалы времени между считываниями будут неслучайными.

100 RANDOMIZE TIMER      'сброс генератора случайных чисел
110 PRINT RND,RND,RND    'печать трех случайных чисел

в результате получаем:  .7122483  .4695052  .9132487

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


   Поскольку регистр  счетчика   канала  таймера  перезагружается
снова  и  снова данным числом (а в промежутках идет счет вниз  до
0), выберите в качестве  загружаемого  в  счетчик значения число,
равное требуемому диапазону случайных чисел.  Например, для полу-
чения случайного значения часа дня загружайте в счетчик 23.
   Лучше всего использовать режим 3 канала 2 (порт 42H) микросхе-
мы  таймера  [2.1.1].  Сначала установите для  счетчика  желаемый
диапазон случайных чисел (в примере  используется 10000, что при-
водит к выдаче случайного числа в диапазоне от 0 до 9999). Затем,
чтобы получить из  канала  случайное  число,  надо подать команду
командному  регистру микросхемы таймера через порт 43H  перенести
текущее значение счетчика  в  регистр  "задвижки",  для чего надо
сбросить  биты 4 и 5.  Этот перенос в регистр задвижки не  мешает
продолжающемуся счету. Затем установите оба бита 4 и 5 командного
регистра, чтобы процессор мог читать из регистра задвижки.  После
этого две инструкции IN дадут  сначала  младший,  а затем старший
байт в регистре AL. Наконец, восстановите первоначальное значение
регистра задвижки, чтобы счет  продолжался  в пределах указанного
диапазона времени.

;---установка адресов портов
COMMAND_REG  EQU   43H     ;адрес командного регистра
CHANNEL_2    EQU   42H     ;адрес канала 2
             CALL  SET_COUNT  ;установка диапазона
              .
;---здесь программа работает, а затем требует случайное число
              .
             CALL  GET_NUMBER ;получение случайного числа
              .
              .

;---начинаем отсчет канала 2
SET_COUNT    PROC
             MOV   AL,10110110B   ;канал 2, режим 2, оба байта
             OUT   COMMAND_REG,AL ;посылаем в командный регистр
             MOV   AX,10000       ;значение счетчика
             OUT   CHANNEL_2,AL   ;посылаем младший байт
             MOV   AL,AH          ;передвигаем старший байт в AL
             OUT   CHANNEL_2,AL   ;посылаем старший байт
             RET
SET_COUNT    ENDP
;---получение случайного числа
READ_NUMBER  PROC
;---пересылаем значение счетчика в регистр задвижки
             MOV   AL,10000110B   ;требуемая команда
             OUT   COMMAND_REG,AL ;посылаем в командный регистр
;---читаем значение счетчика
             MOV   AL,10110110B   ;запрос на чтение/запись
             OUT   COMMAND_REG,AL ;посылаем запрос
             IN    AL,CHANNEL_2   ;получаем младший байт
             MOV   AH,AL          ;временно храним его в AH
             IN    AL,CHANNEL_2   ;получаем старший байт
             CALL  SET_COUNT      ;восстанавливаем задвижку
             SWAP  AH,AL          ;ставим байты на место
             RET                  ;теперь случайное число в AX
READ_NUMBER  ENDP