Аппаратное обеспечение персонального компьютера

Программа RANDOM


Последнее, что мы сделаем с таймером - научимся получать от него случайные числа.

Для генерации случайных чисел лучше всего использовать канал 2 в режиме 3. В регистр счетчика канала мы занесем значение, равное диапазону нужных нам случайных чисел. Например, если мы запишем в регистр число 80 и запустим канал таймера, получаемые случайные числа будут лежать в диапазоне от 0 до 79.

Программа RANDOM (листинг 5.4) получает случайные числа и отображает их в наглядном виде с помощью столбчатой диаграммы.

Листинг 5.4. Файл random\random.с

// =====================================================

// Генерация случайных чисел

//

// (C) Фролов А.В, 1997

//

// E-mail: frolov@glas.apc.org

// WWW:    http://www.glasnet.ru/~frolov

//            или

//         http://www.dials.ccas.ru/frolov



// =====================================================

#include <stdio.h>

#include <conio.h>

#include <dos.h>

void rnd_set(int bound);

int rnd_get(void);

int main(void)

{

  int i, j;

  printf("\nГенератор случайных чисел."

    "\nНажмите любую клавишу,"

       "\nдля завершения работы нажмите <Control+C>"

       "\n");

  for(;;)

  {

    // Устанавливаем диапазон генерации случайных

    // чисел и инициализируем таймер

    rnd_set(80);

    // Ожидаем нажатия клавиши

    getch();

    // После нажатия на клавишу получаем

    // случайное число

    j = rnd_get();

    // Выводим на экран строку символов "-",

    // длина которой равна полученному случайному числу

    for(i=0; i < j; i++)

      putchar(219);

    printf("\n");

  }

  return 0;

}

/**

*.Name         rnd_set

*.Title        Инициализация генератора случайных чисел

*

*.Descr        Эта функция инициализирует канал 2 таймера

*              для использования в качестве генератора

*              случайных чисел

*

*.Proto        void rnd_set(int bound)


*

*.Params       int bound - верхняя граница для генерируемых

*                          случайных чисел.

**/

void rnd_set(int bound)

{

  // Устанавливаем режим 3 для второго канала таймера

  outp(0x43, 0xb6);

  // Загружаем регистр счетчика таймера - сначала

  // младший, затем старший байты

  outp(0x42, bound & 0x00ff);

  outp(0x42, (bound &0xff00) >> 8);

  // Разрешаем работу канала

  outp(0x61, inp(0x61) | 1);

}

/**

*.Name         rnd_get

*.Title        Получение от таймера случайного числа

*

*.Descr        Эта функция получает случайное число от

*              таймера, который был предварительно

*              проинициализирован функцией rnd_set

*

*.Proto        int rnd_get(void)

*

*.Params       Отсутствуют.

*

*.Return       Случайное число в диапазоне от 0, до

*              уменьшенного на 1 значения, заданного в

*              качестве параметра функции rnd_set().

**/

int rnd_get(void)

{

  int i;

 

  // Выдаем команду CLC для фиксирования

  // текущего значения регистра канала 2 таймера

  outp(0x43, 0x86);

  // Вводим младший и старший байты счетчика

  i = inp(0x42);

  i = (inp(0x42) << 8) + i;

 

  return(i);

}


Содержание раздела