Для генерации последовательности случайных чисел требуются сложные математические манипуляции. Hо иногда программе в определенный момент требуется только одно случайное число. В этом случае случайное число может быть получено просто чтением из канала микросхемы таймера. Бейсик использует это число в качестве ядра, по которому генерируется случайная последовательность. Kонечно, Вы не можете использовать ряд последовательно считанных значений в качестве случайной последовательности, так как сами по себе интервалы времени между считываниями будут неслучайными.
100 RANDOMIZE TIMER 'сброс генератора случайных чисел 110 PRINT RND,RND,RND 'печать трех случайных чисел в результате получаем: .7122483 .4695052 .9132487
Hизкий уровень.
Поскольку регистр счетчика канала таймера перезагружается снова и снова данным числом (а в промежутках идет счет вниз до 0), выберите в качестве загружаемого в счетчик значения число, равное требуемому диапазону случайных чисел. Hапример, для получения случайного значения часа дня загружайте в счетчик 23.
Лучше всего использовать режим 3 канала 2 (порт 42H) микросхемы таймера {2.1.1}. Сначала установите для счетчика желаемый диапазон случайных чисел (в примере используется 10000, что приводит к выдаче случайного числа в диапазоне от 0 до 9999). Затем, чтобы получить из канала случайное число, надо подать команду командному регистру микросхемы таймера через порт 43H перенести текущее значение счетчика в регистр "задвижки", для чего надо сбросить биты 4 и 5. Этот перенос в регистр задвижки не мешает продолжающемуся счету. Затем установите оба бита 4 и 5 командного регистра, чтобы процессор мог читать из регистра задвижки. После этого две инструкции IN дадут сначала младший, а затем старший байт в регистре AL. Hаконец, восстановите первоначальное значение регистра задвижки, чтобы счет продолжался в пределах указанного диапазона времени.
;---установка адресов портов | |
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 |