Think
#47
30 августа 2000 |
|
Программистам - Вывод трехсимвольных расширений файлов.
╔════════════════════════════════════════╗ ║ Вывод трехсимвольных расширений файлов ║ ║ в операционной системе 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ощин.
Другие статьи номера:
Похожие статьи:
В этот день... 21 ноября