ГЛАВА 19. ВВОД И ВЫВОД. Драйверы устройств текстового файла. Как сказано в главе 10 "Модуль System", Turbo Pascal позволяет Вам определить Ваш собственный драйвер текстового файла. Драйвер текстового файла - это 4 функции, которые полностью реализуют интерфейс между файловой системой Turbo Pascal и каким-либо устройством. Драйвер на любое устройство определяется 4 функциями: Open, InOut, Flush и Close. Каждая функция имеет заголовок: function DeviceFunc(var F : TextRec) : Integer; где TextRec - это тип записи текстового файла, определенный ранее в разделе "Файловые типы" в главе 3. Каждая функция должна быть откомпилирована в состоянии {$F+}, для использования дальней модели вызова. Значение, возвращаемое функцией, становится результатом, который возвращает IOResult. Значение 0 говорит об успешной операции. Для связи функций интерфейса с устройством с заданным файлом, Вы должны написать свою процедуру Assign (как процедура AssignCrt в модуле Crt). Процедура Assign должна присваивать адреса 4-х функций интерфейса с устройством 4-м указателям на функции в переменной текстового файла. Дополнительно она должна запоминать константу fmClosed в поле Mode, размер буфера текстового файла в BufSize, указатель на буфер текстового файла в BufPtr и очищать строку Name. Например, предположим, что 4 функции интерфейса с устройством называются DevOpen, DevInOut, DevFlush, DevClose, процедура Assign будет: procedure AssignDev(var F: Text); begin with TextRec(F) do begin Mode := fmClosed; BufSize := SizeOf(Buffer); BufPtr := @Buffer; OpenFunc := @DevOpen; InOutFunc := @DevInOut; FlushFunc := @DevFlush; CloseFunc := @DevClose; Name[0] := #0; end; end; Функции интерфейса с устройством могут использовать поле UserData в файловой записи для хранения своей информации. Это поле никогда не модифицируется файловой системой Turbo Pascal. Функция Open. Функция Open вызывается стандартными процедурами Reset, Rewrite и Append для открытия текстового файла, связанного с устройством. При входе поле Mode содержит константу fmInput, fmOutput или fmInOut, показывающую что функция Open была вызвана из Reset, Rewrite или Append. Функция Open готовит файл для ввода или вывода, согласно значению Mode. Если Mode задает fmInOut (Open была вызвана из Append), то она должна быть изменена на fmOutput до возврата из Open. Open всегда вызывается до любой другой функции интерфейса с устройством. По этой причине Assign инициализирует только поле OpenFunc, предоставляя инициализацию остальных векторов функции Open. Основываясь на значении Mode, Open может затем установить указатели либо на функции ввода, либо на функции вывода. Это сохраняет функции InOut, Flush и Close от определения текущего режима. Функция InOut. Функция Inout вызывается стандартными процедурами и функциями Read, Readln, Write, Writeln, Eof, Eoln, SeekEof, SeekEoln и Close, когда необходим ввод или вывод с этого устройства. Когда режим - fmInput, функция InOut читает до BufSize символов в BufPtr^ и возвращает число прочитанных символов в BufEnd. Дополнительно она устанавливает BufPos в 0. Если функция InOut возвращает 0 в BufEnd в результате запроса на ввод, Eof для этого файла становится True. Когда Mode - fmOutput, функция InOut записывает BufPos символов из BufPtr^ и возвращает 0 в BufPos. Функция Flush. Функция Flush вызывается в конце каждой Read, Readln, Write, Writeln. Она может, кроме того, вытеснять буфер текстового файла. Если Mode равно fmInput, функция Flush может устанавливать BufPos, BufEnd в 0 для выталкивания оставшихся (несчитанных) символов в буфер. Эта возможность используется редко. Если Mode - fmOutPut, функция Flush может записывать содержимое буфера, точно так же, как функция InOut, что гарантирует, что текст записанный в устройство, появится на устройстве немедленно. Если Flush ничего не делает, текст не будет передаваться на устройство до тех пор, пока буфер не заполнится или пока не закроется файл. Функция Close. Функция Close вызывается стандартной функцией Close для закрытия текстового файла, связанного с устройством. (Процедуры Reset, Rewrite и Append также вызывают Close, если файл, который они открывают уже открыт). Если Mode - fmOutPut, то - файловая система Turbo Pascal, до вызова функции Close, вызывает InOut, чтобы гарантировать, что все символы были записаны на устройство. Прямой доступ к портам. Для доступа к портам процессора 80х86, Turbo Pascal реализует два предопределенных массива Port и PortW. Оба - одномерные массивы, каждый элемент которых представляет порт, причем адрес порта соответствует его индексу. Тип индекса - слово. Элементы массива Port - типа байт и элементы массива PortW - типа слово. Когда элементу Port или PortW присваивается значение, это значение записывается в указанный порт. Когда элемент Port или PortW используется в выражении - значение читается из указанного порта. Примеры: Port[$20] := $20; Port[Base] := Port[Base] xor Mask; while Port[$B2] and $80 = 0 do {ожидание}; Массивы Port и PortW можно использовать только в присваивании и в выражениях, таким образом, элементы Port и PortW нельзя использовать как изменяемые параметры. Более того, нельзя обращаться ко всему массиву Port или PortW.