Страница 19 из 47
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
|