Справочник программиста на персональном компьютере фирмы 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