Модуль CRT
Назначение модуля CRT программы Турбо Паскаль. Порядок вывода специальных символов. Переменные управления выводом на дисплей и работой клавиатуры. Процедуры работы с экраном и позиционирования курсора. Порядок настройки цвета и подачи звуковых сигналов.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | реферат |
Язык | русский |
Дата добавления | 31.05.2010 |
Размер файла | 59,3 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
1. Модуль CRT
В модуле CRT реализованы специальные процедуры и функции для работы с текстовой информацией на дисплее, позволяющие:
o управлять текстовыми режимами,
o организовывать окна вывода на экран,
o настраивать цвета символов на экране,
o управлять курсором.
В модуль включены функции опроса клавиатуры и процедуры управления встроенным динамиком.
Модуль CRT реализует шестнадцать процедур и четыре функции, его размер составляет не более ЗК. Его стандартное местонахождение - системная библиотека TURBO.TPL.
Для подключения модуля достаточно включить его в директиву USES в самом начале программы:
USES CRT;
При подключении модуля CRT перед выполнением основного блока программы происходит переназначение стандартных файлов, как если бы выполнились операторы:
AssignCRT( Input ) |
{ Связывается системный файл Input с фиктивным устройством CRT} |
|
Reset( Input ) |
{ открытие Input для ввода через CRT} |
|
AssignCRT( Output) |
{ связывается системный файл Output с фиктивным устройством CRT} |
|
Rewrite( Output ); |
{ Файл Output открывается для вывода.} |
Процедура AssignCRT из модуля CRT аналогична по сути процедуре Assign (логический файл, физический файл или устройство), но связывает логический файл с фиктивным устройством CRT.
Переназначение на CRT происходит автоматически, и нет нужды вставлять операторы в текст программы. Они выполняются при подключении модуля CRT.
Если же по каким-либо причинам пользователь хочет восстановить стандартную связь файлов Input и (или) Output, т.е. отказаться от «услуг» подключенного модуля CRT, то в его программе должны быть следующие операторы:
Assign( Input, " ); |
{ Файл Input связывается со стандартным устройством ввода (чтения).} |
|
Reset ( Input ); |
{ Файл Input открывается для чтения.} |
|
Assign ( Output,"); |
{Файл Output связывается со стандартным устройством вывода (записи).} |
|
Rewrite( Output ); |
{ Файл Output открывается для записи.} |
Пустая строка в операторе Assign означает стандартное предопределенное устройство, как правило устройство CON .
Кроме ускорения вывода информации на дисплей, подключение модуля CRT вносит ряд дополнений и расширений в работу стандартных процедур Write, WriteLn, Read и ReadLn.
2. Вывод специальных символов
При подключенном модуле CRT можно выводить на дисплей строки и символы, содержащие в себе управляющие коды (коды 0...31). При этом они не будут оказывать управляющие воздействия, а будут изображаться на дисплее, согласно таблице изображений символов по ASCII-коду. Исключение составляют лишь четыре кода:
Код |
Управляющее воздействие |
Название кода |
|
7 ($07) |
Вызывает один короткий звук динамика |
Bell |
|
8 ($08) |
Сдвигает текущую позицию курсора влево на один символ, если есть куда сдвинуться в пределах строки; в противном случае не имеет эффекта |
Backspace (BS) |
|
10 ($0А) |
Переводит текущее положение курсора на строку ниже, не меняя текущего столбца |
Line Feed (LF) |
|
13 ($00) |
Переводит текущее положение курсора в начало строки |
Carriage Return (CR) |
Приведем пример программы, показывающей работу с управляющими символами.
{Программа вывода изображений управляющих кодов}
Uses CRT; |
{Используется модуль CRT} |
|
Const |
||
SpecialChars : Set of Char==[ #7, #8, #10, #13]; |
{ символы из таблицы} |
|
Ch : Char = #0; |
{ переменная-символ} |
|
Var i: Byte; |
{параметр цикла} |
|
Begin |
||
ClrScr; |
{очистка экрана } |
|
while Ch < #32 do |
{ цикл по #0...#31 } |
|
beginfor i:=1 to 2 do beginWrite ( ' Код', Ord( Ch ):3, ' --> ');if ( Ch in SpecialChars )then Write ( ' Имеет действие' )else Write ( Ch:15 );Ch := Succ( Ch ); { следующий символ }end; {for} |
||
WriteLn |
{закрытие строки } |
|
end; |
{ конец цикла while } |
|
Write ('Нажмите ввод для окончания ...' ); |
||
ReadLn |
{ пауза до нажатия клавиши ввода} |
|
End. |
3. Модификация операторов Read, ReadLn
Операторы Read и ReadLn считывают поступающую информацию по строкам. Так, при вводе с клавиатуры, информация уходит на обработку только после ввода кода закрытия строки (а он вырабатывается клавишей Enter или Return).
При наборе на клавиатуре вводимые символы отображаются на дисплее, а их коды запоминаются в специальном буфере и передаются на обработку только после нажатия клавиши ввода. Пока строка символов не введена, ее можно редактировать, используя клавишу удаления символов Backspace.
После подключения модуля CRT набор клавиш редактирования расширяется комбинациями и клавишами, приведенными в таблице
Клавиша или комбинация |
Действие |
|
Esc |
Стирает все символы в строке ввода |
|
Ctrl+A |
Дублирует клавишу Esc |
|
Ctrl+S |
Дублирует клавишу Backspace |
|
Ctrl+D |
Вызывает очередной символ из введенной ранее, но не стертой строки |
|
Ctrl+F |
Вызывает всю стертую строку ввода |
|
Ctrl+Z |
Вводит строку (заканчивает ввод и вырабатывает признак конца файла, если значение системной переменной модуля CRT CheckEOF=True) |
Комбинация клавиш Ctrl+Z может быть полезна при создании файлов на диске непосредственным вводом с клавиатуры.
4. Системные переменные модуля CRT
При подключении модуля CRT инициализируется ряд его рястемных констант и переменных. Константы используются как параметры в процедурах модуля CRT. Системные же переменные играют роль переключателей режимов работы механизмов ввода-вывода, реализованных в CRT. И константы, и переменные становятся глобальными и доступными программе, использующей модуль CRT, и их не надо описывать среди прочих идентификаторов. Так, например, в модуле CRT определена переменная DirectVideo типа Boolean, и ее стартовое значение равно True. Если надо сменить определяемый ею режим работы густройства CRT, то необходимо вставить в программу строку
UsesCRT; |
{модуль CRT подключен} |
|
… |
{ раздел прочих описаний} |
|
Begin |
||
DirectVideo:=False; |
{ <-- смена режима CRT} |
|
… |
{ собственно программа} |
|
End. |
Но если определить в программе такую же переменную, то доступ к оригиналу из CRT будет заблокирован. Теперь, чтобы все-таки cменить значение системной переменной, надо указывать ее принадлежность в виде определяющего поля:
Uses CRT; |
{ Модуль CRT подклочен} |
|
VAR |
||
DirectVideo : Boolean ; |
{Переопределение системной переменной. Тип может быть и любым другим} |
|
Begin |
||
DirectVideo := False ; |
{не влияет на работу CRT} |
|
CRT.DirectVideo := False; |
{Режим работы CRT меняется.} |
|
End. |
В модуле CRT предопределены восемь идентификаторов
Переменные: тип |
Действие и содержание |
Стартовое значение |
|
CheckSnow, DirectVideo : Boolean |
Управление режимами вывода на дисплей |
False,True |
|
CheckBreak : Boolean |
Управление прерыванием работы программы |
True |
|
CheckEOF : Boolean |
Разрешение или запрет интерпретации символа конца файла (#26) |
False |
|
LastMode : Word |
Переменная для работы с процедурой TextMode |
зависит от режима работы компьютера |
|
TextAttr : Byte |
Значение текущего цветового атрибута для вывода текста на экран |
зависит от последнего режима цвета |
|
WindMax : Word WindMin : Word |
Параметры текущего окна на дисплее |
зависит от режима работы0 |
5. Переменные управления выводом на дисплей
5.1 Переменная CheckSnow
На цветных дисплеях с видеоадаптером CGA могут наблюдаться белые штрихи при смене изображения или выводе информации. Это явление (Snow - в переводе с английского «снег») вызвано рассогласованием между обновлением памяти и сменой изображения. Оно может быть снято программным путем. Механизм снятия «снега» реализован в модуле CRT и является логической переменной CheckSnow. Если ее значение установлено равным True, то будет включен механизм согласования, и эффект «снега» не возникнет. При этом несколько замедлится вывод символов на экран. Для прочих дисплейных адаптеров (EGA, VGA, MDA/Hercules и др.) и для адаптеров CGA без эффекта «снега» имеет смысл поддерживать значение CheckSnow равным False. Это ускорит вывод текстовой информации на экран дисплея. После вызова процедуры TextMode значение CheckSnow всегда автоматически устанавливается равным False.
Переменная CheckSnow зависит от состояния другой переменной модуля CRT - DirectVideo. Если последняя равна False, то значение CheckSnow не играет роли.
5.2 Переменная DirectVideo
Она устанавливает режим записи информации в видеопамять при выполнении операторов Write WriteLn, выводящих информацию на дисплей через механизм CRT (этот механизм включается автоматически при подключении модуля).
Стартовое значение логической переменной DirectVideo равно True. Это же значение устанавливается после каждого вызова процедуры TextMode. При таком значении вывод информации на дисплей производится максимально быстрым способом. После записи значения False в DirectVideo вывод на экран производится медленнее.
6. Переменные управления работой клавиатуры
6.1 Переменная CheckBreak
Эта переменная является логическим переключателем режима работы откомпилированной и скомпанованной программы. Если ее значение равно True (стартовое значение), то нажатие комбинации клавиш Ctrl+Break во время выполнения операций ввода-вывода будет прерывать работу программы. Нажатие Ctrl+Break не во время ввода-вывода информации не имеет эффекта.
Запись значения False в переменную CheckBreak вообще отключает механизм прерывания работы программы комбинацией Ctrl+Break.
Значение переменной можно менять многократно. Иногда полезно разрешать прерывание для одной части программы и запрещать для другой:
Uses CRT; |
{ подключен модуль CRT} |
|
Begin |
||
CheckBreak := False ; |
{ отключение контроля "непрерываемая" часть} |
|
CheckBreak := True; |
{ включение контроля} |
|
… |
{ здесь возможно прервать программу} |
|
End. |
Если на клавиатуре нет клавиши Break, то ее заменяет клавиша ScrollLock, и комбинация прерывания будет соответственно Ctrl+ScrollLock.
6.2 Переменная CheckEOF
Эта переменная разрешает (True) или запрещает (False) ввод с клавиатуры кода признака конца файла (ASCII-код номер 26 - «End-Of-File»), Этот код вырабатывается нажатием комбинации клавиш Ctrl+Z.
Стартовое значение CheckEOF равно False, т.е. нажатие Ctrl+Z введет в строку символ #26, и не будет иметь управляющего воздействия. Если же поменять значение CheckEOF на True, то можно организовать ввод текстов построчно, заканчивая текст признаком конца файла.
В следующем примере функция EOF не имеет параметров. Это означает, что она ожидает ввод кода конца файла с текущего устройства, т.е. с клавиатуры через механизм CRT. Если бы не было строки CheckEOF:=True, то цикл WHILE был бы «вечным».
Program CopyTextToFile; |
{ программа ввода текста в файл } |
|
USES CRT; |
||
VAR |
||
f : Text; |
{ имя логического файла} |
|
s : String[126]; |
{ Максимальное число символов в строке, считываемой через процедуры Read(), ReadLn()} |
|
Begin |
||
ClrScr; |
{ очистка экрана} |
|
Assign (f,'file.txt); |
{ файл на диске - "file.txt"} |
|
Rewrite ( f ); |
{ открытие файла для записи} |
|
WriteLn( 'Введите текст:' ); |
||
CheckEOF := True; |
{ разрешение интерпретации #26} |
|
while not EOF do |
||
begin |
||
ReadLn( s ); |
{считывать строки с клавиатуры, пока не нажато Ctrl+Z} |
|
WriteLn( f, s ) |
{ запись строки в файл на диске} |
|
end; |
||
Close(f); |
{ закрытие файла на диске} |
|
End. |
6.3 Переменная TextAttr
Переменная TextAttr имеет тип Byte и может принимать значения от 0 до 255. В ней хранятся текущие цветовые атрибуты для фона, символов и атрибут мерцания символов. Каждый из восьми битов переменной TextAttr содержит определенную информацию
Номер бита |
7 |
654 |
3210 |
|
Что определяет |
Мерцание 1 - да0 - нет |
Цвет фона (8 значений) 0*16.. 7*16 |
Цвет символов (16 значений, от 0 до 15) |
|
Компонент цвета |
Крас Зел Гол |
Ярк Крас Зел Гол |
Зная структуру этого байта, можно написать три функции опроса текущего цветового режима.
ProgramTest_Colors; |
{анализ текущих цветов } |
|
Uses CRT; |
{подключен модуль CRT} |
|
{ бит номер 7(2^7 = 128) содержит 1(True) или 0 (False)?} |
||
Function IsBlinking: Boolean; |
{ проверка мерцания } |
|
Begin |
||
IsBlinking := ( TextAttr and 128 ) = 128; |
||
End; |
||
{Число в битах 4,5,6 (2^4+2^5+2^6=112), деленное на 16} |
||
FUNCTION GetBackGround : Byte; |
{ номер цвета фона} |
|
BEGIN |
||
GetBackGround := ( TextAttr and 112 ) div 16; |
||
END; |
||
{Число в битах 0, 1, 2 и 3 (1 + 2^1 + 2^2 + 2^3 = 15)} |
||
FUNCTION GetForeGround : Byte; |
{ код цвета символа } |
|
BEGIN |
||
GetForeGround := TextAttr and 15; |
||
END; |
||
BEGIN |
{ Вызовы функций } |
|
WriteLn(` Мерцание:', IsBlinking:5, |
||
` Цвет фона :', GetBackGround:2, |
||
` Цвет символов:', GetForeGround:2); |
||
ReadLn |
{ пауза до нажатия клавиши ввода} |
|
End. |
Результат работы:
Мерцание:FALSE Цвет фона: 0 символов : 3
Переменную TextAttr можно использовать для управления цветовым режимом вывода символов на экран, с помощью формулы
TextAttr: = ЦветСимволов (0..15)+16*ЦветФона(0..7) [+128]
Запись [+128] означает необязательный атрибут мерцания. Когда 128 добавлено, надпись будет мерцать. Если использовать такую форму установки цвета, то становятся почти «бесполезными» процедуры TextColor и TextBackGround, которые изменяют соответствующие биты системной переменной TextAttr.
При «ручном» задании цвета вместо цифр можно указывать цветовые константы, определяемые модулем CRT (они рассматриваются вместе с процедурами TextColor и TextBackGround), например:
TextAttr: = White + 16 * Red + Blink;
Такая формула задает мерцающий белый цвет на красном фоне.
Некоторые особенности возникают при использовании монохромных мониторов (режим Mono). Они способны отображать лишь три градации яркости: «черный», «белый» и «ярко-белый». Название градаций яркости взято в кавычки потому, что реально цвет может быть серым, зеленым или красным в зависимости от монитора. Текст может быть инверсным или подчеркнутым. Все эти атрибуты по-прежнему задаются в переменной TextAttr, но их кодировка уже иная:
Номер бита |
7 |
657 |
3 |
2 1 |
0 |
|
Что определяет |
Мерцание 1 - да0 - нет |
Цветфона/ инверсия |
Яркость 1-да0-нет |
Цвет символа |
Подчеркивание 1-да0-нет |
Строго говоря, возможны лишь определенные значения атрибута:
0 |
(00000000) |
- черные символы на черном фоне; |
|
1 |
(00000001) |
- подчеркнутые неяркие символы, черный фон; |
|
7 |
(00000111) |
- неяркие символы на черном фоне; |
|
9 |
(00001001) |
- подчеркнутые яркие символы, черный фон; |
|
15 |
(00001111) |
- яркие символы на черном фоне; |
|
112 |
(01110000) |
- инверсные цвета (черный на светлом); |
|
127 |
(01111111) |
- инверсные цвета (яркие на светлом); |
Добавление 128 к этим значениям заставит символы (но не фон!) мерцать.
Прочие комбинации битов дадут те же яркостные сочетания, хотя взаимодействия битов здесь далеко не прозрачные. Бит мерцания влияет только на мигание символов. Подчеркивание (бит 0) работает только, когда в битах 6,5,4,2 и 1 стоят нули. В третьем бите может быть единица, добавляющая яркость подчеркнутым символам. Если в битах фона 6,5,4 есть хоть одна единица, а в битах 0,1,2 -- нули, то будет инверсный цвет: черный по белому; если в биты 0, 1, 2 попадет хоть одна единица, то цвета сольются: неяркий белый по белому. И, наконец, если в битах фона есть, бит 3 (яркость) равен единице и в битах цветов символов 0, 1, 2 есть хотя бы одна единица, то будет инверсное изображение -- ярко-белое по белому.
7. Процедуры и функции модуля CRT
Процедуры и функции |
Назначение |
|
ClrScr |
Очистка текущего окна на экране |
|
TextMode(M: Word) |
Установка текстового режима |
|
Позиционирование курсора |
||
GotoXY(X,Y:Byte) |
Установка курсора в столбец X, строку Y |
|
WhereX : Byte |
Выдача номера текущего столбца |
|
WhereY : Byte |
Выдача номера текущей строки |
|
Работа со строками |
||
ClrEOL |
Стирание всех символов в строке, начиная от текущего и до конца строки |
|
InsLine |
Вставка пустой строки на место текущей |
|
DelLine |
Удаление текущей строки |
|
Настройка цвета |
||
TextColor(C: Byte) |
Выбор цвета символов на экране |
|
TextBackGround(C:Byte) |
Выбор цвета фона под символами |
|
HighVideo |
Включение яркости цвета символов |
|
LowVideo |
Выключение яркости цвета символов |
|
NormVideo |
Восстановление цветового режима |
|
Подача звуковых сигналов |
||
Sound (Hz: Word) |
Включение звука с частотой тона Hz в герцах |
|
NoSound |
Выключение звука |
|
Использование встроенного таймера |
||
Delay (ms : Word) |
Задержка процесса (пауза) в ms миллисекунд |
|
Опрос клавиатуры |
||
KeyPressed: Boolean |
Логическая функция для анализа нажатия клавиши |
|
ReadKey : Char |
Функция, возвращающая символ нажатой клавиши |
|
Переназначение стандартных файлов |
||
AssignCRT(VAR f : Text) |
Связь текстового файла f с устройством CRT |
8. Работа с экраном в целом
8.1 Процедура Window(X1,Y1,X2,Y2 : Byte)
Эта процедура устанавливает текущее текстовое окно на экране согласно схеме
(1,1)
Все поле экрана
(Xmax,Ymax)
Координаты диагонали окна X1, Y1, X2 и Y2 всегда отсчитываются от левого верхнего угла экрана в абсолютных координатах и должны удовлетворять следующим условиям:
1 <=X1 < Х2 <= Хmах;
2 <=Y1 < Y2 <= Ymax.
При нарушении этих условий окно не создается.
Параметр Хmах может принимать два значения - 40 и 80, a Ymax - два или одно в зависимости от типа видеоадаптера: 25 (все типы) и 43 или 50 (адаптеры EGA или VGA соответственно).
После выполнения процедуры Window все операции, все действия с экраном относятся к той его части, которая определена координатами , X1, Yl, X2, Y2. Отсчет строк и столбцов для позиционирования курсора теперь производится в координатах текущего окна, и позиция (1,1) -- это левый верхний угол окна. Часть экрана вне окна практически изымается из обращения и становится недоступной стандартным средствам языка.
Сразу после выполнения процедуры курсор устанавливается в позицию (1,1) только что созданного окна. Очистка окна не производится.
При использовании процедуры Window следует помнить, что координаты очередного создаваемого окна всегда даются в «абсолютныхных» экранных координатах, а не в относительных координатах последнего текстового окна.
После окончания работы программы, использующей окна, текущее окно автоматически становится равным полному экрану, так что заботиться об этом нет необходимости. Рассмотрим пример использования окон.
Program Windows; |
{демонстрация текст-окон } |
|
Uses CRT; |
{используется модуль CRT |
|
Var |
||
i: byte; |
{параметр циклов for } |
|
Begin |
{цвет - белый на черном } |
|
TextAttr:=White+16*Black; |
||
ClrScr; |
||
for i:=1 to 112 do |
||
Write('*Полный экран*'); |
{вывод на основной экран } |
|
Repeat |
||
TextAttr:=White+16*Red; |
{цвет - белый на красном } |
|
Window(5,5,20,15); |
{задание одного окна } |
|
for i:=1 to 120 do |
||
write('*Окно 1*'); |
{вывод текста в это окно } |
|
ClrScr; |
{очистка первого окна } |
|
TextAttr:=White+16*Blue; |
{цвет - белый на синем } |
|
Window(40,10,55,20); |
{задание другого окна } |
|
for i:=1 to 120 do |
||
write('*Окно 2*'); |
{вывод текста в это окно } |
|
ClrScr; |
{очистка второго окна } |
|
until KeyPressed; |
{цикл до нажатия клавиши } |
|
End. |
Для программного опроса текущих координат окна на экране введены две специальные системные переменные модуля CRT - WindMax и WindMin.
8.2 Переменные WindMax и WindMin
Эти переменные имеют тип Word и хранят в себе закодированную информации о размерах текущего окна на дисплее (см. процедуру Window). Поскольку максимальные значения координат текстовых окон в столбцах и строках не превышают 255, т.е. могут храниться в одном байте, каждая из переменных хранит одновременно координаты X и Y в младшем и старшем байтах соответственно. Извлечь значения X и Y можно с помощью встроенных функций языка Турбо Паскаль Lo и Hi Схема кодировки такова:
X1:= Lo (WindMin) + 1; |
Х2:= Lo (WindMax) + 1; |
|
Y1:= Hi (WindMin) + 1; |
Y2:= Hi (WindMax) + 1; |
X1, Yl, X2, Y2 - координаты диагонали окна.
Ко всем значениям добавлена единица. Это сделано для совмещения с экранными координатами, у которых начало расположено в верхнем левом углу дисплея и имеет координаты (1,1). В переменных WindMax и WindMin все значения отсчитываются от нуля (начало координат - точка (0,0)).
Переменные WindMin и WindMax являются единственным путем програмного определения размеров текущего текстового окна. Надо только помнить схему кодировки значений и не забывать добавлять единицу.
8.3 Процедура ClrScr
Эта процедура очищает текущее окно, установленное процедурой Window или взятое по умолчанию (т.е. весь экран). При этом окно как бы «закрашивается» цветом фона. Так, например, чтобы сделать поле экрана голубым, необходимо вставить в программу две строки:
TextBackGround (Blue);
ClrScr;
Процедура всегда устанавливает курсор в позицию с координатами (1,1) в текущем текстовом окне.
8.4 Процедура TextMode(М : Word)
Она переключает режимы вывода информации на дисплей. Специально для процедуры в модуле CRT определены восемь констант
Имя= числовое значение |
Разрешение экрана |
Цветовой режим |
|
BW40=0 |
40 х 25 |
Черно-белый при цветном адаптере |
|
C040 = 1 или C40 = 1 |
40 х 25 |
Цветной |
|
BW80= 2 |
80 х 25 |
Черно-белый при цветном адаптере |
|
C040 = 3 или C40 = 3 |
80 х 25 |
Цветной |
|
Mono = 7 |
80 х 25 |
Монохромный на дисплеях MDA/Hercules |
|
Font 8x8 = 256 |
80/40 х 43 80/40 х 50 |
Цветной, адаптер EGA Цветной, адаптер VGA |
|
Все остальные числовые значения до 65535, не являющиеся суммой одной из указанных констант (0,1,2,3,7), и Font 8x8, включают в процедуре TextMode режим С80. |
Эти константы задуманы как параметры процедуры, т.е. предлагается записывать операторы как TextMode (C080), например, для включения цветового режима, хотя достаточно и менее наглядного варианта: TextMode (3). В качестве параметра процедуры TextMode, кроме констант и просто чисел, может быть использована и системная переменная LastMode.
Константа Font8x8 в переводе означает «шрифт 8x8» и включает режимы большей текстовой вместимости дисплеев с видеоадаптерами EGA и VGA, в которых вместо стандартных шрифтов из матриц 8x14 и 8x16 подключаются более «низкие» шрифты с матрицей 8x8, что дает увеличение числа строк до 43 (EGA) или 50 (VGA). Эта константа является дополнительной, т.е. она должна прибавляться к выбранному коду режима, например:
TextMode (C080 + Font8x8)
В этом случае включится цветовой режим С080 одновременно со сменой разрешающей способности экрана с 80x25 на 80x43(50). Просто вызов TextMode(Font8x8) равносилен вызову TextMode (BW40+Font8x8).
В большинстве случаев режимы BWxx и С0хх не отличаются друг от друга, что всегда имеет место при использовании дисплеев с раздельным управлением цветовыми лучами (так называемые RGB-дисплеи).
Режим Mono, включенный при цветном видеоадаптере, может сбить палитру цветов для их «проявления» на монохромных дисплеях.
Кроме смены режима текстового изображения, команда TextMode обновляет значения системных переменных и производит переустановку цветовых атрибутов. Можно считать, что происходит выполнение следующих действий:
Window( 1,1,Xmax,Ymax ); |
{окно делается равным всему экрану} |
|
DirectVideo True; |
{включается режим прямого вывода} |
|
CheckSnow False; |
{отключается снятие "снега" (CGA)} |
|
NormVideo; |
{устанавливается стартовый атрибут} |
|
ClrScr; |
{экран очищается} |
|
LastMode <-- Параметр; |
{параметр в TextMode запоминается} |
Нормальное место процедуры TextMode -- в начале программы и/или в самом ее конце для включения и выключения режимов программы. С процедурой TextMode тесно связана системная переменная модуля CRT LastMode.
8.5 Переменная LastMode
В этой переменной сохраняется текстовый режим работы, который установлен последним выполнением процедуры TextMode.
Ее значения (типа Word) соответствуют разрешенным значениям папаметров TextMode. Самое первое значение LastMode соответствует режиму, из которого запускалась программа.
С помощью переменной LastMode восстанавливается исходный текстовый режим работы после выполнения программы.
Uses CRT; |
{ программа использует модуль CRT} |
|
Var |
||
StartMode : Word; |
{ здесь сохранится значение режима} |
|
Begin |
||
StartMode : = LastMode; |
{ сохранение стартового режима} |
|
... |
{ работа в разных режимах} |
|
TextMode ( StartMode ) |
{ восстановление режима} |
9. Позиционирование курсора
9.1 Процедура GotoXY (X, Y: Byte)
С помощью этой процедуры можно устанавливать курсор в столбец X и строку Y текущего окна. При этом последующая операция вывода текста на дисплей поместит первый символ выводимой строки в позиции (X,Y).
Процедура GotoXY использует систему координат текущего текстового окна, т.е. координаты (1,1) соответствуют левому верхнему углу окна.
Если аргументы процедуры X и Y окажутся вне текущего окна, то ее вызов не будет иметь никакого эффекта. Нижние разрешенные значения для X и Y всегда равны 1, а верхние определяются размерами текущего окна. С помощью процедуры GotoXY можно выводить строки на экран вертикально.
Например
Uses CRT; |
{подключен CRT} |
|
Procedure VertStr(X,Y Byte; S : String ); |
||
VAR |
||
Len: Byte absolute S; |
{ длина строки S } |
|
i :Byte; |
{ параметр цикла } |
|
Begin |
||
for i: =1 to Len do begin |
||
GotoXY( X, Y+Pred(i) ); |
{ назначение позиции вывода} |
|
Write( S[i] ); |
{ вывод очередного символа} |
|
end {for} |
||
End; |
||
Begin |
||
ClrScr; |
{ очистка экрана } |
|
VertStr( 5,5, 'Вертикально!' ); |
{ вывод строки} |
|
ReadLn |
{ пауза} |
|
End. |
При выводе символов или другой информации по мере необходимости на экране происходит прокрутка, или сдвиг, изображения. Это всегда имеет место при выводе кодов конца строки (LF, код 10) в последней строке окна операторами WriteLn и ReadLn или когда выводимая строка не умещается в той же последней строке текстового окна. А, например, вывод типа
GotoXY (5, 25); Write (`строка');
не вызовет сдвига вверх, потому что оператор Write не переводит строки. Однако вывод хотя бы одного символа в правый нижний угол текстового окна вызовет прокрутку:
GotoXY (80, 25); Write (`*');
и символ '*' окажется уже в 24-й строке, а не в 25-й. Эту особенность всегда приходится учитывать при построении программ, работающих со всем полем экрана. В этой программе приведен еще пример, основанный на применении процедуры GotoXY. В нем вводится процедура, которая закрашивает прямоугольную область на экране любым символом в текущем цветовом атрибуте, причем заполнение области происходит по спирали.
Uses Crt; |
||
{Процедура закраски квадратной области экрана} |
||
{С диагональю (XO,YO)-(X,Y) символом Ch} |
||
{ ms - период задержки при закраске} |
||
Procedure Spiral(X0,Y0,X,Y:byte; ms:word; Ch:char); |
||
Var |
||
height, width, i: byte; |
||
c: integer; |
||
Begin |
||
c:=1; |
{ начальное значение с } |
|
width:=X-X0+1; |
{ начальная ширина поля } |
|
height:=Y-Y0+1; |
{ начальная высота поля } |
|
repeat |
{ основной цикл } |
|
for i:=1 to width do begin |
{ вправо/влево } |
|
GoToXY(X,Y); write(Ch); |
{ ставим символ } |
|
if (Y>Hi(WindMax)) and (X>Lo(WindMax)) |
||
then begin |
{ !!! Обработка} |
|
GoToXY(1,1); InsLine; |
{ особого случая} |
|
end; |
||
Delay(ms); |
{ задержка} |
|
X:=X-c; |
||
end; {for i} |
||
X:=X+c; |
{ восстановление X. после цикла} |
|
Dec(height); |
{ поле закраски стало ниже} |
|
for i:=1 to height do begin |
{ вверх/вниз} |
|
Y:=Y-c; |
||
GoToXY(X,Y); write(Ch); |
||
Delay(ms); |
||
end; {for i} |
||
X:=X+c; |
||
Dec(width); |
{ Поле закраски стало уже} |
|
X:=X+c; |
{ и стартовое X сдвинулось.} |
|
c:=-1*c; |
{ смена направления} |
|
until (height<1) or (width<1); |
{ условие окончания} |
|
GoTo(1,1); |
{ курсор в начало } |
|
End; |
||
Var i:byte; |
{ -- ПРИМЕР ИСПОЛЬЗОВАНИЯ -- } |
|
Begin |
||
ClrScr; |
||
Spiral(1,1,80,25,2,#176); |
||
for i:=1 to 10 do begin |
||
TextAttr:=i; |
||
Spiral(2*i,i,5*i,2*i,4,Chr(47+i)); |
||
end; {for} |
||
Readln; |
{ пауза до нажатия клавиши ввода} |
|
End. |
Комментарий к особому случаю. При попытке записи в правый нижний угол окна символа происходит сдвиг (прокрутка) изображения вверх. Во избежание этого закраска начинается с наибольших значений X и Y, и если они совпадают с углом окна, то сразу же проводится сдвиг изображения назад, вниз.
9.2 Функции WhereX и WhereY
Эти функции нужны для программного опроса текущего местоположения курсора в текстовом окне. Они возвращают значения координат курсора в текущем окне. Можно считать, что пара функций WhereX и WhereY обратна процедуре GotoXY.
Правила нахождения столбца (WhereX) и строки (WhereY) курсора несложны. Их всего четыре:
1. сразу после команды GotoXY (X,Y) функции возвращают значения X и Y соответственно;
2. после оператора Write курсор стоит сразу за последним символом выводимой строки (если не выводятся специальные символы типа #8, #10 или #13);
3. после операторов Read, ReadLn, WriteLn курсор стоит в первом столбце строкой ниже;
4. после команд, относящихся ко всему окну (экрану), таких как ClrScr, TextMode, Window, курсор имеет координаты (1,1).
Функции WhereX и WhereY могут эффективно использоваться в программах, работающих с пользователем в режиме полноэкранного диалога (редактора текстов, таблиц и т.п.).
10. Работа со строками
10.1 Процедура ClrEOL
Эта процедура может применяться как для стирания «хвостов» строк, так и для раскраски чистого экрана в полоску максимально быстрым способом.
Смысл процедуры содержится в ее названии - «очистка до конца строки». Она стирает все символы в строке, начиная с текущей позиции курсора и до правого края текущего окна. Вместо стираемых символов она ставит пробелы, при этом цвет строки определяется цветовым атрибутом фона.
Процедура не имеет других эффектов - даже курсор при выполнении процедуры не меняет своих координат. Программа иллюстрирует как стирание строк, так и раскраску экрана.
Uses Crt; |
{ Примеры применения процедуры ClrEOL} |
|
Var i: byte; |
{счетчик цикла} |
|
Begin |
||
TextAttr:=White; |
||
ClrScr; |
{очистка экрана} |
|
for i:=1 to 100 do |
||
write('*CtrlEOL*'); |
{текст на экране } |
|
Delay(1000); |
{пауза в 1 с } |
|
TextAttr:=16*Green; |
{ зеленый цвет фона } |
|
for i:=1 to 10 do begin |
{ Стирание концов строк} |
|
GoToXY(i*8,i); |
{ установка курсора} |
|
ClrEOL |
{ собственно очистка} |
|
End; |
||
TextAttr:=16*Blue; |
{ синий цвет фона} |
|
for i:=12 to 25 do |
{ Штриховка в полоску} |
|
if Odd(i) then begin |
{ если 1 нечетное, то} |
|
GoToXY(1,i); ClrEOL; |
{закрасить всю строку.} |
|
end; |
||
Readln; |
{ пауза до нажатия ввода} |
|
TextAttr:=White; |
||
ClrScr; |
{ восстановление цвета} |
|
End. |
10.2 Процедуры InsLine и DelLine
Эти процедуры также работают со строками. Они позволяют «прокручивать» часть текстового окна или весь экран вверх и вниз.
Процедура InsLine вставляет пустую строку на место той, в которой находится в текущий момент курсор. Все нижние строки, начиная с нее, смещаются вниз на одну строку. Самая нижняя строка уйдет за нижнее поле окна и исчезнет. Традиционно при вводе множественной информации «с экрана» строки начинают двигаться вверх, освобождая внизу окна место для очередного запроса. Аналогично, длинные тексты пробегают по экрану снизу вверх. При помощи процедуры Insline можно организовать такую выдачу информации на экран, при которой изображение смещается сверху вниз. Для этого достаточно перед выводом очередной строки поставить в программе два оператора
GoToXY (1, 1); InsLine;
как это сделано в следующем примере.
{ Пример использования процедуры InsLine}
Uses Crt; |
||
Var |
||
i:byte; |
{счетчик цикла} |
|
Begin |
||
ClrScr; |
{очистка экрана} |
|
for i:=1 to 25 do |
{цикл вывода строк} |
|
begin |
||
GoToXY(1,1); |
||
InsLine; |
{расчистка места} |
|
writeln('Строка N', i); |
{вывод строки} |
|
Delay(200); |
{задержка в 200 мс} |
|
end; |
||
readln; |
{пауза до нажатия} |
|
End. |
Процедура DelLine удаляет строку, в которой находится курсор, подтягивая на ее место все нижестоящие строки. При этом освобождается самая нижняя строка окна. Процедура DelLine реализует прокрутку всего окна или его части.
При использовании этих процедур надо не забывать, что освобождающиеся строки будут закрашены текущим цветом фона.
Интересных эффектов можно достичь, применяя сочетания этих двух процедур. Рассмотрим простейшую программу, реализующую эффект «подвижного текста», который может быть использован при написании игр или заставок к программам
{ Пример применения процедур InsLine/DelLine}
Uses Crt; |
||
Var |
||
i:byte; |
{ переменная для циклов } |
|
Begin |
||
ClrScr; |
||
GoToXY(1,2*7); |
{начало абзаца текста} |
|
for i:=1 to 7 do |
{вывод семи строк в абзац} |
|
writeln('Ins/Del Line'); |
||
GoToXY(1,1); |
{вывод курсора из абзаца} |
|
Repeat |
{Цикл : } |
|
for i:=1 to 7 do DelLine; |
{поднять абзац на 7 строк } |
|
for i:=1 to 7 do InsLine; |
{и опустить на 7 строк } |
|
until KeyPressed; |
{пока не нажата какая-либо клавиша} |
|
End. |
11. Настройка цвета
11.1 Процедуры TextCoIor (C: Byte) и TextBackGround(C: Byte)
Действие этих процедур сводится к записи в системную переменную TextAttr модуля CRT определенных значений. Процедура TextColor устанавливает цвет символов, a TextBackround - цвет фона. Специально для этих процедур определены константы, соответствующие различным цветам
Константа |
Число |
Цвет |
Процедуры |
|
Black |
= 0 |
Черный |
TextColor, TextBackround |
|
Blue |
=1 |
Синий |
TextColor, TextBackround |
|
Green |
=2 |
Зеленый |
TextColor, TextBackround |
|
Cyan |
=3 |
Голубой |
TextColor, TextBackround |
|
Red |
=4 |
Красный |
TextColor, TextBackround |
|
Magenta |
=5 |
Фиолетовый |
TextColor, TextBackround |
|
Broun |
=6 |
Коричневый |
TextColor, TextBackround |
|
LightGray |
= 7 |
Ярко-серый |
TextColor, TextBackround |
|
DarkGray |
= 8 |
Темно-серый |
TextColor |
|
LightBlue |
=9 |
Ярко-синий |
TextColor |
|
LightGreen |
=10 |
Ярко-зеленый |
TextColor |
|
LightCyan |
=11 |
Ярко-голубой |
TextColor |
|
LightRed |
=12 |
Ярко-красный |
TextColor |
|
LightHagenta |
=13 |
Ярко-фиолетовый |
TextColor |
|
Yellow |
=14 |
Желтый |
TextColor |
|
White |
=15 |
Белый |
TextColor |
|
Blink |
=128 |
Мерцание |
TextColor (как слагаемое) |
Удобство использования процедур в том, что не надо пересчитывать значения, как это делалось при непосредственном изменении TextAttr. Достаточно указать нужный цвет, подставив соответствующую константу, например:
TextColor LightRed + Blink);
TextBackGround (Green);
В результате будет установлен мигающий ярко-красный цвет символов на зеленом фоне.
Для фона разрешенными являются только восемь значений «неярких цветов».
11.2 Процедуры установки яркости High Video и LowVideo
Эти процедуры не имеют параметров, и устанавливают бит яркости системной переменной TextAttr в значения «да» (1) или «нет» (0), превращая обычные цвета (Black… LightGray) в «яркие» (DarkGray…White).
Процедуры High Video и LowVideo хорошо работают при оформлении диалога и каких-либо других задач, связанных с выводом текстов на экран
{Пример применения LowVideo и HighVideo}
Uses Crt; |
||
Begin |
||
TextColor(LightGray); |
{неяркий серый цвет} |
|
TextBackGround(Black); |
{черный цвет фона} |
|
ClrScr; |
||
Write('Легко использовать'); |
||
HighVideo; |
{включение яркости} |
|
write(' яркость'); |
||
LowVideo; |
{выбор низкой яркости} |
|
writeln(' для выделения слов'); |
||
Readln; |
{пауза до нажатия ввода} |
|
ClrScr; |
||
End. |
11.3 Процедура NormVldeo. После выполнения этой процедуры восстанавливаются тот цветовой атрибут (цвет фона, символов и мерцание), который был на момент начала работы программы.
12. Подача звуковых сигналов. Процедуры Sound (Hz : Word ) и Nosound
Позволяют работать с динамиком ПК. Процедура Sound включает звук с частотой тона в герцах. После включения звука программа дальше. Если сама программа «забудет» выключить звук, то придется добавлять к ней в конец оператор NoSound прекращающийся аккомпанемент динамика. Набор звуковых всегда должна завершать процедура NoSound, выключающая динамик, хотя вызовов процедур Sound может быть сколько угодно. В таком случае звук не будет прекращаться, но будет менять свою частоту согласно заданным аргументам. Можно, например, в начало каждой поставить команду Sound с различными частотами. Тогда при работе программа будет издавать трели.
Очень часто процедуры Sound и NoSound используются вместе с процедурой задержки времени Delay (ms). Например, строка программы
Sound (300); Delay (1000); NoSound;
издает ровный звук на частоте 300 Гц продолжительностью 1 с. Но при этом во время звучания программа будет «стоять».
В качестве примера приведем несложную процедуру печати строк в звуковом сопровождении:
{ Процедура звуковой печати строк}
Uses Crt; |
||
Procedure SoundType(X,Y:byte; S:string; ms:word); |
||
Const |
||
Hz=50; |
{частота тона} |
|
Var i: byte; |
{параметр цикла} |
|
Begin |
||
Dec(X); |
{сдвиг значения} |
|
for i:=1 to Length(S) do begin |
||
Sound(Hz); Delay(ms); |
{первый сигнал} |
|
GoToXY(X+i,Y); write(S[i]); |
{печать символа} |
|
Sound(2*Hz); Delay(ms); |
{второй сигнал} |
|
NoSound; |
{снятие звука} |
|
end; |
||
End; |
||
Begin |
{ -- ПРИМЕР ВЫЗОВА -- } |
|
ClrScr; |
||
SoundType(20,10,'0123456789aaa9876543210',150); |
||
Readln; |
{ пауза до нажатия клавиши ввода } |
|
End. |
Если разделять вызовы Sound с разными частотами небольшими задержками, то можно «синтезировать» довольно сложные звуки.
13 Опрос клавиатуры
13.1 Функция KeyPressed
Эта функция возвращает логическое значение True, если в буфере ввода с клавиатуры имеется хотя бы один символ, и False, если буфер пуст.
Когда программа стартует, буфер обычно пуст. Но любое нажатие клавиши (кроме клавиши регистров Ctrl, Shift, Alt и переключателей типа NumLock, CapsLock и т.п.) занесет ее код в буфер. Коды в буфере будут храниться до тех пор, пока они либо не будут считаны, либо буфер не будет очищен самой программой.
Очищают буфер полностью, процедуры Read и ReadLn, а также операция Reset над файлом, связанным с консолью. Процедуры Read и ReadLn получают ввод с клавиатуры через еще один специальный буфер. (Этим, кстати, и объясняется ограничение в 126 символов для одной вводимой строки -- такова емкость буфера строки.)
Имеется еще одна функция, очищающая буфер клавиатуры -- ReadKey. Но в отличие от Read и ReadLn, которые очищают весь буфер после своей работы, ReadKey как бы «вынимает» последовательно введенные в него символы по одному за каждое обращение.
Место логической функции KeyPressed - в опросе состояния клавиатуры:
if KeyPressed then Действие ;
Функция KeyPressed является флагом не только сиюминутного нажатия, но я нажатий вообще во время работы программы. Так, если пользователь заденет несколько клавиш во время «молчаливого» счета своей задачи, то внешне ничего не произойдет. Но буфер запомнит все, что было «введено», и функция KeyPressed совершенно резонно не захочет работать так, как от нее ожидалось бы.
Для очистки буфера перед опросом и опроса клавиатуры в реальном времени, рассмотрим вторую функцию работы с клавиатурой.
13.2 Функция опроса ReadKey
Эта функция опрашивает буфер клавиатуры со всеми рассмотренными выше последствиями и особенностями.
Функция возвращает всегда один символ, т.е. одно значение типа Char. Есть две важные особенности:
1. полученные функцией символы никогда не отражаются на дисплее, т.е. ввод символа происходит вслепую;
2. режим работы ReadKey зависит от состояния буфера ввода: содержит ли он символы или пуст. Если в буфере что-то есть, то ReadKey вернет первый символ в буфере (тот, который был введен раньше остальных) и удалит этот символ из буфера. Но если буфер пуст, то функция ReadKey приостанавливает работу программы и ждет, пока не будет нажата какая-либо клавиша, генерирующая символьный код.
Используя эти особенности, можно построить несколько довольно полезных конструкций, что мы и сделаем в качестве иллюстрации (переменная Ch должна быть типа Char):
While KeyPressed do ch: =ReadKey; {очистка буфера ввода}
Repeat untit KeyPressed; {ожидание нажатия побои клавиши}
Последний цикл завершится, когда в буфер попадет какой-либо символ. Программа должна в конце очистить буфер.
14. Переназначение стандартных файлов
14.1 Процедура AssignCRT( VAR f : Text
Перенаправляет вывод на фиктивное устройство CRT. Устройство CRT активизируется при подключении модуля CRT директивой USES. Оно начинает выполнять функции ввода-вывода средствами библиотеки Турбо Паскаля. При подключении модуля CRT стандартный ввод и вывод автоматически связывается с механизмами CRT. Но если вводятся файлы, отличные от стандартных, то для использования устройства CRT надо эти файлы связывать с ним. А это возможно только через процедуру AssignCRT.
Рассмотрим каркас программы, перенаправляющей файлы.
Uses Crt; |
{ используется модуль CRT} |
|
VAR |
||
f : Text; |
{ текстовый логический файл} |
|
BEGIN |
||
Assign( f, 'LPT2' ); |
{ файл f связан с принтером} |
|
Rewrite( f ); |
{ файл f открыт для вывода} |
|
WriteLn( f, ... ); |
{ вывод данных на печать} |
|
Close( f ); |
{ файл f (LPT2) закрыт} |
|
AssignCRT( f ); |
{ файл f связан с устройством CRT} |
|
{ и использует его механизмы быстрого вывода.} |
||
Rewrite( f ); |
{ файл f открыт для вывода} |
|
WriteLn( f, ... ); |
{ быстрый вывод на монитор} |
|
Close( f ); |
{ файл все равно надо закрыть} |
|
END. |
Отметим, что никаким другим способом нельзя связать объявленный в программе файл с фиктивным устройством CRT. Попытки использовать для этого процедуру Assign, типа
Assign (f, `CRT'); Rewrite (f);
организуют на диске файл с именем 'CRT' (случай Rewrite (f)) или вообще дадут ошибку (случай Reset (f), если файла 'CRT' не существует).
При использовании вывода в устройство CRT уже нельзя будет организовать перенаправление потоков ввода-вывода при запуске откомпилированной программы в MS-DOS из командной строки. Но перенаправление станет возможным, если связать файлы в программе со стандартным устройством MS-DOS.
Подобные документы
Функции ввода с клавиатуры и вывода на экран, алгоритм вывода чисел. Генерация звуковых сигналов в ПЭВМ. Принципы работы видеосистемы: адресация и режимы работы адаптера CGA, режим работы дисплея. Таблица векторов прерываний в работе клавиатуры.
отчет по практике [700,4 K], добавлен 23.11.2010Использование графических возможностей Турбо Паскаля, подключение графического модуля Graph. Графические функции и процедуры. Общая структура графической программы. Построение фигур, определение цветов и стилей, работа с текстом, сообщения об ошибках.
реферат [109,3 K], добавлен 28.04.2010Основные сведения о системе программирования Турбо Паскаль. Структура программы на Паскале и ее компоненты. Особенности и элементы языка Турбо Паскаль. Порядок выполнения операций в арифметическом выражении, стандартные функции и оператор присваивания.
лекция [55,7 K], добавлен 21.05.2009Развертывание системы на жестком диске, диалоговая система программирования Турбо Паскаль, запуск программы и выполнение задания. Функциональные клавиши и их назначение. Текстовый редактор, средства создания и редактирования текстов программ, курсор.
реферат [18,6 K], добавлен 01.04.2010Особенности программирования на языке Паскаль в среде Турбо Паскаль. Линейные алгоритмы, процедуры и функции. Структура данных: массивы, строки, записи. Модульное программирование, прямая и косвенная рекурсия. Бинарный поиск, организация списков.
отчет по практике [913,8 K], добавлен 21.07.2012Лингвистическая концепция языка Паскаль. Интегрированная инструментальная оболочка. Основы построения программ на ТП 7.0. Алфавит языка и специфика использования символов. Простые типы данных: константы и переменные. Циклические конструкции и операции.
курсовая работа [284,6 K], добавлен 02.07.2011Общая характеристика языка программирования Турбо Паскаль: операторы, циклы, файлы. Процедуры и функции модуля Crt. Структурная и функциональная схема программы учета учащихся, таблица идентификаторов. Список и описание использованных подпрограмм.
курсовая работа [702,9 K], добавлен 29.01.2011Правила описания множественных типов данных, приемов использования множеств и операций над множествами в Паскаль-программах. Разработка в Турбо Паскале программы вывода всех согласных букв, которые входят хотя бы в одно слово заданного предложения.
контрольная работа [30,8 K], добавлен 25.12.2010Особенности использования графического режима в среде Турбо Паскаль. Типы драйверов. Инициализация графики. Построение изображения на экране. Графические примитивы и работа с текстом. Разработка и реализация программ в среде Турбо Паскаль "Графика".
курсовая работа [1,2 M], добавлен 26.09.2014Освоение технологии структурного программирования и применения стандартных методов работы с одномерными массивами при разработке и создании программы на языке Турбо Паскаль. Разработка программы методом пошаговой детализации с помощью псевдокода.
реферат [276,9 K], добавлен 27.02.2008