Главная страница  Межпроцессное взаимодействие (состязание) 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 [ 91 ] 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

Ctty.task j;>

(ndle evente

Простые / символы /

Escape-последовательности

(OLrt phar

v pause esca


Специальные символы

Конец строки

(roll screen

flush

Рис. 3.26. Основные подпрограммы, используемые при выводе на консоль. Штриховой линией обозначено прямое копирование символов в буфер ramqueue подпрограммой cons write

Эта подпрограмма при каждом вызове выполняет для указанного устройства как запись, так и чтение. В случае с консолью это означает, что сначала будут обработаны еще не принятые клавиатурные данные. Если необработанного ввода нет, переданные символы добавляются к другим символам, ожидающим вывода. Затем вызывается процедура cons write, выполняющая вывод для отображаемых в память экранов. Последняя использует подпрофамму phys copy, чтобы скопировать блок символов от пользовательского процесса в локальный буфер, причем, возможно, это действие будет повторено несколько раз, так как локальный буфер вмещает только 64 байта. Когда буфер укомплектовывается, каждый 8-битный байт переносится в другой буфер, ramqueue, представляющий собой массив 16-битных слов. Дополнительный байт заполняется текущим значением байта атрибутов, который определяет цвет символов, цвет фона и некоторые другие параметры текста. Когда это возможно, символы копируются напрямую в ramqueue, но некоторые символы, например управляющие символы, образующие ESC-последовательности, необходимо обрабатывать особо. Кроме того, специальная обработка требуется тогда, когда позиция символа превышает ширину экрана или когда ramqueue заполняется. В этом случае, чтобы передать символы и выполнить необходимые дополнительные действия, вызывается функция out char. Так, каждый раз когда на последней строке экрана принимается



символ перевода строки, делается вызов подпрограммы scroll screen, а parse escape принимает символы, образующие ESC-последовательность. Обычно out char вызывает подпрограмму flush, которая копирует ramqueue в видеопамять при помощи ассемблерной подпрограммы mem vid copy. Функция flush также вызывается после того, как в ramqueue передается последний символ, чтобы гарантировать, что отображены все символы. Конечный результат работы flush - команда, предаваемая чипу видеоконтроллера 6845 с целью отобразить в нужном месте курсор.

Байты, поступающие от пользовательского процесса, было бы логично выводить по одному, в цикле. Тем не менее, для систем класса Pentium с защитой памяти более эффективно предварительно накапливать их в ramqueue, а затем копировать весь блок при помощи вызова mem vid copy. Интересно, что в MINIX эта техника появилась в то время, когда система работала на более старых процессорах, не имевших защищенного режима. Предшественник mem vid copy решал другую проблему, проблему синхронизации. Дело в том, что у старых экранов запись в видеопамять необходимо было производить при очистке экрана, во время вертикального обратного хода луча, чтобы избежать появления мусора на экране. Сейчас такое устаревшее оборудование не поддерживается, так как это приводит к слишком большим накладным расходам. Тем не менее сама техника копирования целого блока из ramqueue применяется и поныне, хотя и для другой цели.

Доступная консоли область видеопамяти задается полями c start и c limit структуры console. Текущее положение курсора хранится в полях c column и c row. Координатам (0,0) соответствует верхний левый угол экрана, с этого места аппаратное обеспечение начинает заполнять экран. Изображение начинается с адреса, задаваемого значением c org, и занимает 80 х 25 символов (4000 байт). Другими словами, чип 6845 извлекает из видеопамяти два байта по адресу c org и отображает в левом верхнем углу символ, используя второй байт для задания цветов, мигания и прочих атрибутов. Затем чип извлекает из памяти следующее двухбайтовое слово и отображает символ в позиции (1, 0). Этот процесс продолжается до тех пор, пока не будет достигнута позиция (79, 0), после чего начинается рисование второй строки экрана, начиная с координат (О, 1).

При включении компьютера экран очищается, и данные записываются в видеопамять, начиная с положения c start, а c orig присваивается то же значение, что и c start. Таким образом, первая строка текста выводится в верхней строке экрана. Когда вывод переходит на следующую строку, под управлением ли символа перевода строки, либо в результате заполнения верхней строки экрана, новые символы помещаются по адресу, равному c start плюс 80. Со временем все 25 строк экрана окажутся заполнены и потребуется прокрутка экрана. Некоторым программам, например текстовым редакторам, требуется возможность прокручивать экран и в обратном направлении, когда курсор находится в верхней строке экрана и требуется перейти выше по тексту.

Существует два подхода к решению задачи прокрутки экрана. Когда применяется программная прокрутка, символу с координатами (О, 0) всегда соответствует один и тот же адрес видеопамяти, с нулевым смещением относительно c start. Видеоконтроллер всегда выводит этот символ на одном месте, благодаря тому.



что в c org хранится один и тот же адрес. Когда необходимо выполнить прокрутку, область видеопамяти, начинающаяся со второй строки экрана (смещение 80 относительно c start), копируется в начало занимаемой консолью области (смещение 0). Положение самой занимаемой экраном области памяти не меняется. В результате содержимое экрана перемещается на одну строку вверх. Эта операция занимает время, необходимое для сдвига 80 х 2000 слов памяти. При аппаратной прокрутке данные никуда не перемещаются. Вместо этого контроллер получает инструкцию начинать выводить данные с другого адреса, например с 80-го слова. Для этого новое значение записывается в c org, чтобы его можно было использовать в дальнейщем, а также копируется в нужный регистр видеоконтроллера. Такая схема будет работать, если контроллер достаточно умен и при достижении конца видеопамяти (адрес в c limit) переходит на ее начало (адрес в c start), или же при такой емкости видеопамяти, когда в ней помещается более одного экрана, то есть 80 х 2000 слов. У старых терминальных устройств обычно была небольшая память, зато они умели переходить на начало памяти, достигнув конца, и благодаря этому поддерживали аппаратную прокрутку. У современных контроллеров памяти обычно намного больше, чем это необходимо для хранения одного экрана, но перескакивать на начало они не научены. Так, контроллер с видеопамятью 32 768 байт может хранить в памяти 204 полные строки по 160 байт каждая и может 179 раз выполнить аппаратную прокрутку, прежде чем невозможность прыжка станет проблемой. Затем потребуется копирование области памяти с целью переместить данные с последних 24 строк в начало видеобуфера. Когда это делается, нижняя строка экрана заполняется пробелами для гарантии, что она пуста.

При конфигурировании виртуальных консолей доступная видеопамять поровну делится между всеми консолями, для чего соответствующим образом инициализируются поля c start и c limit каждой консоли. Это оказывает влияние на прокрутку. Любому видеоконтроллеру, обладающему достаточно большой для поддержки нескольких виртуальных консолей памятью, время от времени необходима программная прокрутка, хотя номинально поддерживается аппаратная реализация сдвига экрана. Чем меньший объем памяти доступен каждому виртуальному дисплею, тем чаще требуется программная прокрутка. Предел достигается, когда создается максимально возможное количество виртуальных консолей. При этом каждая прокрутка будет программной.

Положение курсора относительно начала видеопамяти можно вычислить, исходя из c column и c row, но быстрее хранить его в явном виде (c cur). Когда на экран выводится символ, он записывается в память по адресу c cur, который после вывода обновляется, как и значение в c column. Все поля структуры console, оказывающие влияние на текущее положение вывода и начало экрана в памяти, перечислены в табл. 3.12.

При обработке символов, изменяющих текущую позицию (то есть символов перевода строки, забоя и т. д.), соответственным образом изменяются значения полей c column, c row и c cur. Это делается в конце кода процедуры flush, где находится вызов функции set 6845, которая устанавливает регистры видеоконтроллера.



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 [ 91 ] 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

© 2000 - 2018 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования.