На главную
Подписка
Новости










Главная / MS-DOS / MS-DOS. РУКОВОДСТВО РАЗРАБОТЧИКА / Глава 9 / Прямая запись на экран Сделать домашней страницей Добавить в избранное Написать писмо

НАЗАД СОДЕРЖАНИЕ ВПЕРЁД

Прямая запись на экран

Зная о регистрах маски бита и маски матрицы, а также о регистрах-защелках EGA, мы имеем достаточно информации для создания программы на языке Си, которая пишет точку непосредственно в экранную память. Эта программа работает быстрее, чем аналогичная ей программа BIOS адаптера EGA. При работе с 8-МГц персональным компьютером АТ, EGA BIOS поместит на дисплей в течении 1 миллисекунды 2.56 точки (2.56 точек/мс). Программа, представленная в листинге 9-3, помещает на дисплей 7.55 точек/ мс - скорость возрастает на 185 процентов. Недостатком является то, что fastdot() может работать только в графических режимах EGA, и для работы с другой дисплейной картой необходимо переписать программу.


Следующие макрокоманды позволят программе 9-3 установить маску бита, маску матрицы, а также другие внутренние регистры.


         #define EGA_GRFX(index, value) { outp(0X3CE, index) ; \
                                          outp(0x3CF, value) ;}
         #define EGA_SQNC(index, value) { outp(0X3C4, index) ; \
                                          outp(0x3C5, value) ;}

Первая макрокоманда, EGA_GRFX, принимает в качестве аргументов номер индекса, соответствующего функции, выбранной из чипа контроллера графики 1 и 2, а также значение, направляемое чипу. Графические чипы 1 и 2 EGA управляют доступом к битовым массивам. (Тем не менее, они реально представляют собой два чипа, расположенные по одному адресу, и могут считаться одним чипом.) Адрес индекса графических чипов 1 и 2 0x3CE, а адрес данных 0x3CF. Макрокоманда охватывает два оператора языка Си. Первый оператор посылает чипам значение индекса, а второй оператор посылает данные.


Вторая макрокоманда, EGA_SQNC, сходна с EGA_GRFG. Однако, EGA_SQNC имеет доступ к другому чипу, чипу планировщика EGA, направляя индекс и данные различным портам вывода. Наибольший интерес для чипа планировщика представляет регистр маски матрицы.


Следующие две макрокоманды дают подпрограмме доступ к адресу сегмент:смещение в любом месте адресного пространства персонального компьютера:


         #define PEEK_BYTE(s,o) (*(char far *) ( (long)(s)<<16 | (o) ))
         #define PEEK_WORD(s,o) (*(int far *) ( (long)(s)<<16 | (o) ))

Заключительные макрокоманды комбинируют предыдущие. Макрокоманда GET_CRT_COLS() возвращает значение для использования в качестве числа битов на линию в графических режимах EGA. Число битов на линию равно числу символов на линию, и это число является адресом 0x40:0x4A в области данных BIOS. Макрокоманды EGA_BIT_MASK и EGA_MAP_MASK устанавливают соответственно регистры маски бита и маски матрицы.


         #define GET_CRT_COLS()   PEEK_WORD(0x40, 0x4A)
         #define EGA_BIT_MASK(mask)   EGA_GRFX(8, mask)
         #define EGA_MAP_MASK(mask)   EGA_SQNC(2, mask)

Вместе эти макрокоманды облегчают чтение и понимание кодов программы, написанной для манипулирования аппаратными средствами EGA. Эти макрокоманды далее используются во всех программах этой главы.


Большинство регистров EGA доступны только для записи. Каждая программа, использующая дисплей, нуждается в информации о состоянии EGA, так как только записываемые регистры нельзя считать. Поэтому, самым безопасным состоянием регистров EGA является состояние EGA BIOS, установленное по умолчанию. Кроме того, EGA BIOS предполагает, что при записи символов на дисплей регистры EGA находятся в состоянии, установленном по умолчанию. Если регистр маски бита установлен в состояние маскировки бита, символы будут нечитаемыми. Для маски бита и маски матрицы состоянием, установленным по умолчанию, является выключенный режим маскировки, поэтому, установка маски 0xF и 0xFF в последних двух строках fastdot() восстанавливает состояние по умолчанию. Преимуществом регистров VGA является то, что они доступны и для чтения и для записи. (Различия между EGA и VGA были использованы в программе EGACHECK.C для обнаружения карты VGA.) Поэтому, регистры VGA должны быть оставлены в состоянии по умолчанию.


Убедитесь, что Вы понимаете, как вычисляется в программе, приведенной в листинге 9-3, адрес байта элемента изображения:


         char far *rgen = (char far *)(0xA0000000L +
                          (col >> 3) +
                          (row * GET_CRT_COLS()) );

Адрес бита вычисляется как ((строка х байты на строку) + столбцы / 8 бит на байт). В целях повышения скорости деления колонок на 8 используется оператор правого сдвига языка Си, >>.


                         Листинг 9-3. Программа FASTDOT.C
         ---------------------------------------------------------------

         /* fastdot.c */
         #include 
         fastdot(row, col, color)
         /* Эта программа поместит точку в буфер дисплейной памяти EGA
         ** Использовать только в графических режимах EGA (13, 14, 15
         ** или 16) и с памятью EGA от 128К
         ** ИЛИ с VGA в режимах 13, 14, 15, 16, 17 или 18
         */
         int  row, col, color;
         {
         char latch ;
         /* Установить адрес изменяемого байта */
         /* Байт буфера = А000:((строка*байтов/строка)+столбец/8) */
           unsigned char far *rgen = (char far *)(0xA0000000L +
                                     (col >> 3)  +
                                     (row * GET_CRT_COLS()) ) ;
         /* Вычислить изменяемый бит: */
           char bit_mask = (char)(0x80 >> (col & 7)) ;
           EGA_BIT_MASK(bit_mask) ;   /* установить маску бита */
           latch = *(rgen) ;          /* подготовить защелки */
           *(rgen) = 0 ;              /* очистить бит */
           EGA_MAP_MASK(color) ;      /* установить цвет */
           *(rgen) = 0xFF ;           /* установить бит */
           EGA_MAP_MASK(0xF) ;        /* сбросить маску матрицы */
           EGA_BIT_MASK(0xFF) ;       /* сбросить маску бита */
         }
         ---------------------------------------------------------------

Для того, чтобы узнать число бит на строку, значение которого может быть равно 40 байтам в видеорежиме 13 или 80 байтам в режимах с 14 по 16, посмотрите на значение числа символов на строку в области данных BIOS (адрес 0х40:0х4A). Число бит на строку и число символов на строку в графических режимах EGA одно и то же. Результат всего вычисления добавляется к 0xA0000000L, представляющим собой сегмент графических режимов EGA. Полное значение затем сбрасывается в указатель far.


Номер бита в байте, соответствующем изменяемому элементу изображения, вычисляется как (col~&~7). Как только будет известен номер бита, маска бита устанавливается в значение 0х80 >> номер бита (0х80 - это 010000000b).


         while(page){
          rgen += PEEK_WORD(0x40, 0x4C) ; /* добавить длину страницы */
          --page ;}

Предыдущая программа предполагает, что используется страница 0. Для того, чтобы получить возможность адресации к странице, отличной от 0, вставьте следующие строки: где page - номер адресуемой страницы. Слово по адресу 0х40:0х4С содержит длину в байтах дисплейного буфера, используемого подпрограммами EGA BIOS.


Испытайте программу, приведенную в листинге 9-2, заменив оператор dot оператором fastdot(). Она в два-три раза быстрее, чем подпрограмма BIOS.


НАЗАД СОДЕРЖАНИЕ ВПЕРЁД

Hosted by uCoz