Sinclair Club
#04
25 мая 2001 |
|
Программирование - Вывод трехсимвольных расширений файлов в операционной системе TR-DOS.
┌────────────────────────────────────────┐ │ Вывод трехсимвольных расширений файлов │ │ в операционной системе TR-DOS │ └────────────────────────────────────────┘ ────────────────────────────────────────── (с) Иван Рощин, г.Москва ────────────────────────────────────────── В 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 KL_F_CUT m SPY MPS VIVID M NOSTALGY Y s_play2d txt Теперь хотелось бы сказать несколько слов об имени диска. В TR-DOS под имя диска отводится восемь символов, а само имя расположено по смещению #F5 в служебном (девятом) секторе мулевой дорожки. Как видим, в этом секторе остаются свободными еще три байта, а значит, имя диска может быть увеличено до одиннадцати символов. Действительно, 11-символьное имя довольно часто используют. Hо тут есть один нюанс... Если вы хотите присвоить диску 11 - символьное имя, то старший бит последнего байта обязательно должен быть установлен. Дело в том, что подпрограмма печати строки в TR - DOS (которая используется для вывода имени диска при выполнении команды CAT) заканчивает печатать строку или при встрече нулевого байта, или когда старший бит последнего напечатанного символа был установлен (при печати символа старший бит сбрасывается). Если печатается обычное имя из восьми символов, все проходит нормально, так как за ним следуют три нулевых байта, а вот при печати 11- символьного имени, если старший бит последнего байта не установлен, то процедура не остановится, напечатав имя, а будет печатать дальше и дальше, заполняя экран мусором. Соответственно, если вы пишете программу для работы с диском и хотите поддержать 11-символьное имя диска, то при печати последнего символа имени ваша процедура печати должна сбрасывать его старший бит. ══════════════════════════════════════════ (Радиолюбитель. Ваш компьютер 7/2000)
Другие статьи номера:
Похожие статьи:
В этот день... 14 декабря