Страница Ивана Рощина > Статьи >

© Иван Рощин, Москва

ZXNet: 500:95/462.53
E-mail: bestview@mtu-net.ru
WWW: http://www.ivr.da.ru

Вывод трёхсимвольных расширений файлов в операционной системе TR-DOS

Радиолюбитель. Ваш компьютер» 7/2000)
Дополненная версия. Дата последнего редактирования: 10.11.2002.

В TR-DOS каждому файлу ставится в соответствие 16-байтовый описатель, находящийся в каталоге диска. Как видно из табл. 1, в этом описателе для расширения файла предусмотрен лишь один символ.

Табл. 1
Смещение от начала Длина Комментарий
0 8 Имя файла
8 1 Расширение файла
9 2 Стартовый адрес файла
(для BASIC — длина программы и переменных)
11 2 Длина файла в байтах
(для BASIC — длина программы без учёта длины переменных)
13 1 Длина файла в секторах
14 1 Номер сектора начала файла
15 1 Номер дорожки начала файла

Но в последнее время всё шире используется более информативное трёхсимвольное расширение файла (как в MS-DOS):

Табл. 2
Смещение от начала Длина Комментарий
0 8 Имя файла
8 3 Расширение файла
11 2 Длина файла в байтах
13 1 Длина файла в секторах
14 1 Номер сектора начала файла
15 1 Номер дорожки начала файла

Видно, что длина расширения увеличилась за счёт использования двух байтов, в которых раньше хранился стартовый адрес файла.


Если вы пишете какую-либо программу для работы с файлами, неплохо было бы предусмотреть в ней вывод трёхсимвольных расширений. Но тут появляется проблема: заранее не известно, с какими файлами придётся иметь дело, а расширение у файлов может быть как трёхсимвольным, так и односимвольным. Таким образом, для каждого конкретного файла ваша программа должна правильно определить длину расширения. Если же считать расширение всегда трёхсимвольным, то каталог диска будет выглядеть неаккуратно:

boot     B±
ZX_WIN   ZIP
******** ZIP
S_PLAY2d BБ
BACKUM   GTR
BUZZ16_1 MPS
FL_SH_EI MPS
KL_F_CUT m!ћ
SPY      MPS
VIVID    MEљ
NOSTALGY Y ђ
s_play2d txt

Попробуем сделать так: определим, какие последовательности из трёх байтов являются допустимыми трёхсимвольными расширениями, и если в описателе файла окажется недопустимая последовательность, то будем считать, что у этого файла односимвольное расширение.


Сначала перечислим список требований, которым должно удовлетворять трёхсимвольное расширение:

  1. Все три символа — коды в диапазоне #20..#7F.
  2. В расширении не может быть одновременно прописных и строчных латинских букв.
  3. Несмотря на пункт 2, расширения XAS, xAS, XaS, xaS являются допустимыми (файлы с такими расширениями создаёт ассемблер XAS).
  4. Если первый символ — «B», то расширение не может быть трёхсимвольным, потому что у BASIC-файлов следующие два байта содержат длину программы и переменных и не могут являться символами расширения.

Теперь рассмотрим процедуру, определяющую длину расширения файла в соответствии с этими требованиями.


Процедура рассчитана на компиляцию в ассемблере ZX ASM 3.10, и при компиляции в другом ассемблере вам может потребоваться заменить команду «PUSH HL,DE,BC» на три команды: «PUSH HL», «PUSH DE» и «PUSH BC». Соответственно, команду «POP BC,DE,HL» тоже нужно будет заменить на три команды: «POP BC», «POP DE» и «POP HL».

Входные параметры: HL указывает на первый символ расширения. Регистр H не должен быть равен нулю.

Выходные параметры: регистры остаются без изменений (кроме аккумулятора), а флаг Z несёт информацию о длине расширения: если флаг установлен — расширение трёхсимвольное; если сброшен — односимвольное.

Длина процедуры всего семьдесят два байта, она максимально оптимизирована, и, по-видимому, сделать её короче без ущерба для функциональности не получится.


Текст процедуры:

ANALYS_EXT PUSH HL,DE,BC

;Проверка на BASIC:

           LD   A,(HL)
           CP   "B"
           JR   Z,ANALYS_NO

;Проверка на XAS, xAS, XaS, xaS:

           RES  5,A
           CP   "X"
           JR   NZ,ANALYS_EX1

           INC  HL
           LD   A,(HL)
           RES  5,A
           CP   "A"
           JR   NZ,ANALYS_EX2

           INC  HL
           LD   A,(HL)
           CP   "S"
           JR   Z,ANALYS_YES

           DEC  HL
ANALYS_EX2 DEC  HL

;Изначально D=#FF, E=0. Как только
;встречаем символ A..Z или a..z,
;добавляем его к D по AND и к E по OR.
;В пятом бите 0, если буква прописная,
;и 1, если буква строчная. Допустимы
;лишь варианты 0,0,0 и 1,1,1. Если
;вариант 0,0,0 (все буквы прописные), то
;5-й бит D = 0 и 5-й бит E = 0. Если
;вариант 1,1,1 (все буквы строчные), то
;5-й бит D = 1 и 5-й бит E = 1. Для
;других вариантов (когда есть и 0, и 1)
;5-й бит D = 0 и 5-й бит E = 1. Видим,
;что для вариантов 0,0,0 и 1,1,1 5-й бит
;от D XOR E будет равен 0, а для других
;вариантов он будет равен 1, таким
;образом, можно отличать допустимые
;варианты от недопустимых.

ANALYS_EX1 LD   DE,#FF00
           LD   BC,3*256+%00100000

ANALYS_EX3 LD   A,(HL)
           CP   C           ;=CP #20
           JR   C,ANALYS_NO
           CP   #80
           JR   NC,ANALYS_NO;не #20..#7F
           OR   C
           CP   "a"
           JR   C,ANALYS_EX4
           CP   "z"+1
           JR   NC,ANALYS_EX4
           LD   A,(HL)
           AND  D
           LD   D,A
           LD   A,(HL)
           OR   E
           LD   E,A

ANALYS_EX4 INC  HL
           DJNZ ANALYS_EX3

           LD   A,D
           XOR  E
           AND  C
           JR   Z,ANALYS_YES

ANALYS_NO  OR   H  ;Сбрасываем флаг Z
                   ;(т.к. H<>0, то и
                   ;результат операции
                   ;OR будет <> 0).

;При передаче управления на ANALYS_YES
;по JR - флаг Z всегда будет установлен!

ANALYS_YES POP  BC,DE,HL
           RET

Вот, например, как выглядит каталог диска, где для каждого файла длина расширения определялась с помощью этой процедуры:

boot     B
ZX_WIN   ZIP
******** ZIP
S_PLAY2d B
BACKUM   GTR
BUZZ16_1 MPS
FL_SH_EI MPS
KL_F_CUT m
SPY      MPS
VIVID    M
NOSTALGY Y
s_play2d txt

Теперь хотелось бы сказать несколько слов об имени диска. В TR-DOS под имя диска отводится восемь символов, а само имя расположено по смещению #F5 в служебном (девятом) секторе нулевой дорожки.

Как видим, в этом секторе остаются свободными ещё три байта, а значит, имя диска может быть увеличено до одиннадцати символов. Действительно, 11-символьное имя довольно часто используют. Но тут есть один нюанс…

Если вы хотите присвоить диску 11-символьное имя, то старший бит последнего байта обязательно должен быть установлен. Дело в том, что подпрограмма печати строки в TR-DOS (которая используется для вывода имени диска при выполнении команды CAT) заканчивает печатать строку или при встрече нулевого байта, или когда старший бит последнего напечатанного символа был установлен (при печати символа старший бит сбрасывается). Если печатается обычное имя из восьми символов, всё проходит нормально, так как за ним следуют три нулевых байта, а вот при печати 11-символьного имени, если старший бит последнего байта не установлен, то процедура не остановится, напечатав имя, а будет печатать дальше и дальше, заполняя экран мусором.

Соответственно, если вы пишете программу для работы с диском и хотите поддержать 11-символьное имя диска, то при печати последнего символа имени ваша процедура печати должна сбрасывать его старший бит.

Дополнение

Как выяснилось, одно из требований к трёхсимвольному расширению (ранее сформулированное так: все три символа — коды в диапазоне #20..#7F) нуждается в некотором уточнении.

Во-первых, символ с кодом 96 (обратная кавычка) не является допустимым и, следовательно, должен быть исключён из данного диапазона.

Во-вторых (об этом мне сообщил Max Vasilyev), трёхсимвольное расширение не должно начинаться с пробела (например, « ab») или содержать вторым символом пробел («a b»). Иначе говоря, пробелом может быть лишь последний символ расширения.

Соответственно, процедура определения длины расширения файла теперь должна выглядеть так:

ANALYS_EXT PUSH HL,DE,BC

           LD   BC,3*256+%00100000

;Проверка на BASIC:

           LD   A,(HL)
           CP   "B"
           JR   Z,ANALYS_NO

;Проверка: первый или второй символ - пробел?

           INC  HL
           LD   A,(HL)
           CP   C            ;=CP #20
           JR   Z,ANALYS_NO

           DEC  HL
           LD   A,(HL)
           CP   C            ;=CP #20
           JR   Z,ANALYS_NO

;Проверка на XAS, xAS, XaS, xaS:

           RES  5,A
           CP   "X"
           JR   NZ,ANALYS_EX1

           INC  HL
           LD   A,(HL)
           RES  5,A
           CP   "A"
           JR   NZ,ANALYS_EX2

           INC  HL
           LD   A,(HL)
           CP   "S"
           JR   Z,ANALYS_YES

           DEC  HL
ANALYS_EX2 DEC  HL

ANALYS_EX1 LD   DE,#FF00

ANALYS_EX3 LD   A,(HL)
           CP   C            ;=CP #20
           JR   C,ANALYS_NO
           CP   #80
           JR   NC,ANALYS_NO ;не #20..#7F
           CP   96
           JR   Z,ANALYS_NO  ;"`"
           OR   C
           CP   "a"
           JR   C,ANALYS_EX4
           CP   "z"+1
           JR   NC,ANALYS_EX4
           LD   A,(HL)
           AND  D
           LD   D,A
           LD   A,(HL)
           OR   E
           LD   E,A

ANALYS_EX4 INC  HL
           DJNZ ANALYS_EX3

           LD   A,D
           XOR  E
           AND  C
           JR   Z,ANALYS_YES

ANALYS_NO  OR   H

ANALYS_YES POP  BC,DE,HL
           RET

В регистровой паре HL, напомню, должен задаваться адрес первого символа расширения (H<>0!), а результат работы процедуры возвращается во флаге Z (установлен — расширение трёхсимвольное, сброшен — односимвольное).

Другие мои статьи о TR-DOS:

1. 

«Доступ к порту #1F в TR-DOS 5.03». «ZX-Ревю» 1—2/1997.

2. 

«О сокращении времени форматирования». «ZX-Ревю» 1—2/1997.

3. 

«TR-DOS: как не допустить ошибки?». «ZX-Ревю» 5—6/1997.

4. 

«Работа с диском при включённых прерываниях». Adventurer #9, «Чёрная ворона» #3, «Радиолюбитель. Ваш компьютер» 6/2000 (дополненная версия).

5. 

«Усовершенствованный алгоритм определения смены диска». «Радиолюбитель. Ваш компьютер» 9/2000.

6. 

«Расширения файлов TR-DOS». «Радиолюбитель. Ваш компьютер» 12/2000, «Радиомир. Ваш компьютер» 9/2001 (под псевдонимом BV_Creator).

7. 

«Обрубаем файлам „хвост“». «Радиомир. Ваш компьютер» 4/2002.

8. 

«Использование избыточной информации для защиты файлов от повреждений». «Радиомир. Ваш компьютер» 11/2002.

9. 

«Проверка корректности файловой структуры дисков TR-DOS». «Радиомир. Ваш компьютер» 6/2004.

Страница Ивана Рощина > Статьи >