Для генерации последовательности случайных чисел требуются сложные математические манипуляции. 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 |