Справочник программиста на персональном компьютере фирмы IBM. Вывод на терминал - Вывод на экран одного символа

ОГЛАВЛЕНИЕ

     4.3.1 Вывод на экран одного символа.


   Все процедуры для  вывода  символа  на  экран  в BIOS и DOS (а
также  в  Бейсике) помещают символ в текущую  позицию  курсора  и
автоматически передвигают курсор на одну позицию вправо.  Все они
переносят вывод на следующую строку при достижении конца  строки,
если не сделано специальных  указаний  отбрасывать все символы за
80-м столбцом [4.2.2]. Важное отличие между отдельными процедура-
ми состоит в том, что некоторые  вместе  с символом пишут также и
его атрибуты, а некоторые этого не делают.
   Как  в языках высокого, так и в языках низкого уровня, символы
могут выводиться на  экран  без  использования  обычных  операций
печати.   Вместо этого используется прямое отображение в  память,
при котором коды символов и их атрибуты прямо засылаются в ячейки
памяти видеобуфера, соответствующие определенной позиции  курсора
на экране. Буфер начинается с  адреса  B000:0000 для монохромного
адаптера и с адреса B800:0000 - для цветного графического адапто-
ра и PCjr.  EGA использует те же самые адреса в аналогичных режи-
мах экрана.  Позиции с четными номерами (начиная с нуля) содержат
коды ASCII символов, а позиции с нечетными номерами - байты атри-
бутов.  На рис. 4-2 показан участок памяти видеобуфера.  При этих
операциях позиция курсора не  меняется  и  он может быть выключен
при  желании  [4.2.3].  Вместо курсора надо  хранить  переменные,
служащие указателями на текущую позицию.

   Высокий уровень.


   Бейсик выводит как  отдельные  символы,  так и целые строки, с
помощью  одних и тех же операторов PRINT и WRITE.   Как  правило,
используется  PRINT; WRITE - это один из вариантов со специальны-
ми, редко используемыми форматами вывода. PRINT работает с данны-
ми трех видов.  Он выводит содержимое как строковых, так и число-
вых переменных, например, PRINT S$ или PRINT X.  Он выводит также
символы, вставленные (в кавычках) внутрь самого оператора  PRINT,
например, PRINT "This words are printed". Он выводит также симво-
лы,  соответствующие  кодам ASCII, включенным в оператор PRINT  в
виде операторов CHR$, например,  PRINT  CHR$(65),  что приводит к
выводу на экран символа A (код ASCII #65).
   В  одном  операторе PRINT могут выводиться много  данных,  при
этом все три формы данных могут быть перемешаны. Отдельные данные
отделяются запятой или точкой с запятой. Запятая приводит к тому,
что следующие данные будут выводиться  со следующей позиции табу-
ляции данной строки.  Точка с запятой приводит к тому, что данные
печатаются на экране подряд, не  разделенные  пробелами (отметим,
что PRINT вставляет пробел перед выводом любой числовой  перемен-
ной, а WRITE не делает этого). Обычно оператор PRINT автоматичес-
ки  делает перевод на новую строку при завершении, таким  образом
следующий  такой  оператор  начнет  вывод  с новой строки экрана.
Чтобы перенос на новую строку не происходил надо в конце операто-
ра PRINT поставить точку с запятой, например, PRINT S$;.
   Для установки позиции курсора  перед  выводом используется оп-
ератор LOCATE. Без оператора LOCATE PRINT всегда начинает вывод с
первой позиции строки, в которой находится курсор. Последователь-
ные  операторы  PRINT заполняют экран до тех пор, пока  не  будет

записана 24-я строка, после  чего  экран  сдвигается вверх, с тем
чтобы  следующий оператор PRINT снова выводил 24-ю строку.  PRINT
может выводить в 25-й  строке  только  при  помощи  LOCATE; и это
также приводит к автоматическому сдвигу экрана вверх.  Чтобы зап-
ретить сдвиг надо окончить оператор PRINT точкой с запятой. Одна-
ко  этот  метод не сработает в последних позициях строк 24 и  25.
Для заполнения этих позиций без сдвига экрана Вы должны использо-
вать отображение в память, как показано ниже.
   Вы можете включать управляющие символы [7.1.9] внутрь операто-
ра PRINT для того чтобы  реализовать  перемещения  курсора внутри
строки.  Например, если Вы поместите в строку CHR$(13), то в этой
точке будет сделан возврат каретки.   Если Вы выведете оператором
PRINT строку "One"+CHR$(13)+"Two"+CHR$(13)+"Three", то в  резуль-
тате каждое слово будет  выводиться  с  новой строки.  Коды ASCII
28-31  сдвигают  курсор на одну  позицию  соответственно  вправо,
влево, вверх и вниз. Оператор PRINT не содержащий данных приводит
к  выводу  возврата каретки и, таким образом, следующий  оператор
PRINT будет выводить на строке через одну.
   Прямое отображение в память  существенно  увеличивает скорость
вывода на экран в Бейсике. Оно особенно полезно при конструирова-
нии табличного вывода, когда формы могут достигать правого нижне-
го  угла экрана.  Сначала надо установить указатель  сегмента  на
&HB000, а затем  использовать  оператор  POKE  для засылки байтов
памяти.  Прилегающие по горизонтали символы отстоят друг от друга
на два байта, разделяемые  байтом  атрибутов.   Для 80-символьных
экранов прилегающие по вертикали символы отстоят на 160 байт друг
от друга (2 байта для каждого  символа  и атрибутов). В следующих
двух  примерах  вдоль  границы экрана рисуется  рамка,  используя
символы псевдографики.  В первом примере чаще используется опера-
тор  PRINT, а во втором используется исключительно прямое отобра-
жение в память. Отметим, что и в первом случае приходится исполь-
зовать прямое отображение в память в последних столбцах строк  24
и 25, чтобы избежать сдвига экрана.

   Использование PRINT:

 10 CLS: KEY OFF              'очистка экрана
 20 DEF SEG = &HB000          'указываем на видеобуфер
 30 LOCATE 1,1: PRINT CHR$(201)   'левый верхний угол
 40 LOCATE 1,80: PRINT CHR$(187)  'правый верхний угол
 50 LOCATE 1,24: PRINT CHR$(186)  '
 60 LOCATE 1,25: PRINT CHR$(200)  '
 70 POKE 3838,186                 'позиция 80 строки 24
 80 POKE 3998,188                 'позиция 80 строки 25
 90 FOR N=2 TO 79                 'горизонтальные линии
100 LOCATE 1,N: PRINT CHR$(205);: LOCATE 25,N: PRINT CHR$(205)
110 NEXT                          '
120 FOR N=2 TO 23                 'вертикальные линии
130 LOCATE N,1: PRINT CHR$(186): LOCATE N,80: PRINT CHR$(186)
140 NEXT

   Использование прямого отображения в память:

 10 CLS: KEY OFF               'очистка экрана
 20 DEF SEG = &HB000           'буфер монохромного дисплея
 30 POKE 0,201                 'левый верхний угол
 40 POKE 158,187               'правый верхний угол
 50 POKE 3840,200              'левый нижний угол
 60 POKE 3998,188              'правый нижний угол
 70 FOR N=2 TO 156 STEP 2      'горизонтальные прямые
 80 POKE N,205: POKE N+3840,205  'как верхняя, так и нижняя
 90 NEXT
100 FOR N=160 TO 3680 STEP 160 'вертикальные прямые
110 POKE N,186: POKE N+158,186 'правая и левая
120 NEXT