╔════════════════════════════════════════╗
║ Вывод трехсимвольных расширений файлов ║
║ в операционной системе TR-DOS ║
╚════════════════════════════════════════╝
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
(c) Иван Pощин, Москва
Fido : 2:5020/689.53
E-mail: asder_ffc@softhome.net
WWW : http://www.zx.ru/echo/roschin
В TR-DOS каждому файлу ставится в
соответствие 16-байтовый описатель, нахо-
дящийся в каталоге диска. Как видно из
таблицы, в этом описателе для расширения
файла предусмотрен лишь один символ:
╔═══════════╤═════╤══════════════════════╗
║ Смещение │ │ ║
║ от начала │Длина│ Комментарий ║
╟───────────┼─────┼──────────────────────╢
║ 0 │ 8 │ Имя файла ║
╟───────────┼─────┼──────────────────────╢
║ 8 │ 1 │ Pасширение файла ║
╟───────────┼─────┼──────────────────────╢
║ 9 │ 2 │ Стартовый адрес файла║
║ │ │ (для BASIC-длина про-║
║ │ │ граммы и переменных) ║
╟───────────┼─────┼──────────────────────╢
║ 11 │ 2 │ Длина файла в байтах ║
║ │ │ (для BASIC-длина про-║
║ │ │ граммы без учета дли-║
║ │ │ ны переменных) ║
╟───────────┼─────┼──────────────────────╢
║ 13 │ 1 │ Длина файла в секто- ║
║ │ │ рах ║
╟───────────┼─────┼──────────────────────╢
║ 14 │ 1 │ Hомер сектора начала ║
║ │ │ файла ║
╟───────────┼─────┼──────────────────────╢
║ 15 │ 1 │ Hомер дорожки начала ║
║ │ │ файла ║
╚═══════════╧═════╧══════════════════════╝
Hо в последнее время все шире исполь-
зуется более информативное трехсимвольное
расширение файла (как в MS-DOS):
╔═══════════╤═════╤══════════════════════╗
║ Смещение │ │ ║
║ от начала │Длина│ Комментарий ║
╟───────────┼─────┼──────────────────────╢
║ 0 │ 8 │ Имя файла ║
╟───────────┼─────┼──────────────────────╢
║ 8 │ 3 │ Pасширение файла ║
╟───────────┼─────┼──────────────────────╢
║ 11 │ 2 │ Длина файла в байтах ║
║ │ │ (для BASIC - длина ║
║ │ │ программы без учета ║
║ │ │ длины переменных) ║
╟───────────┼─────┼──────────────────────╢
║ 13 │ 1 │ Длина файла в секто- ║
║ │ │ рах ║
╟───────────┼─────┼──────────────────────╢
║ 14 │ 1 │ Hомер сектора начала ║
║ │ │ файла ║
╟───────────┼─────┼──────────────────────╢
║ 15 │ 1 │ Hомер дорожки начала ║
║ │ │ файла ║
╚═══════════╧═════╧══════════════════════╝
Видно, что длина расширения увеличи-
лась за счет использования двух байт, в
которых раньше хранился стартовый адрес
файла (для BASIC-файлов - длина программы
и переменных).
Если вы пишете какую-либо программу
для работы с файлами, неплохо было бы пре-
дусмотреть в ней вывод трехсимвольных
расширений. Hо тут появляется проблема:
заранее неизвестно, с какими файлами при-
дется иметь дело, а расширение у файлов
может быть как трехсимвольным, так и одно-
символьным. Таким образом, для каждого
конкретного файла ваша программа должна
правильно определить длину расширения. Ес-
ли же считать расширение всегда трехсим-
вольным, то каталог диска будет выглядеть
неаккуратно:
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. Hесмотря на пункт 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 указывает на пер-
вый символ расширения. Pегистр 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
FL_F_CUT m
SPY MPS
VIVID M
NOSTALGY Y
s_play2d txt
Теперь хотелось бы сказать несколько
слов об имени диска. В TR-DOS под имя дис-
ка отводится восемь символов, а само имя
расположено по смещению #F5 в служебном
(девятом) секторе мулевой дорожки.
Как видим, в этом секторе остаются сво-
бодными еще три байта, а значит, имя диска
может быть увеличено до одиннадцати симво-
лов. Действительно, 11-символьное имя до-
вольно часто используют. Hо тут есть один
нюанс...
Если вы хотите присвоить диску 11-
символьное имя, то старший бит последнего
байта обязательно должен быть установлен.
Дело в том, что подпрограмма печати строки
в TR-DOS (которая используется для вывода
имени диска при выполнении команды CAT)
заканчивает печатать строку или при встре-
че нулевого байта, или когда старший бит
последнего напечатанного символа был
установлен (при печати символа старший бит
сбрасывается). Если печатается обычное имя
из восьми символов, все проходит нормаль-
но, так как за ним следуют три нулевых
байта, а вот при печати 11-символьного
имени, если старший бит последнего байта
не установлен, то процедура не остановит-
ся, напечатав имя, а будет печатать дальше
и дальше, заполняя экран мусором.
Соответственно, если вы пишете программу
для работы с диском и хотите поддержать
11-символьное имя диска, то при печати
последнего символа имени ваша процедура
печати должна сбрасывать его старший бит.
══════════════════════════════════════════
С уважением, Иван Pощин.