|
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ощин.
Другие статьи номера:
Похожие статьи:
В этот день... 1 января
SibNews #08,
Woot! #01,
Spectrum Magazine #01,
ACNews #25,
Psychoz #14,
ACNews #14,
Last 128 #08,
Last 128 #06,
Last 128 #05,
Last 128 #04,
Last 128 #03,
Last 128 #02,
Last 128 #09,
Last 128 #3.5,
Last 128 #8.025,
Sinclair Club #05,
Last 128 #M!R 01,
Fantadrom #01,
Buzz #20,
Last 128 #01,
DonNews #13,
Nicron #120,
Promised Land #01,
Inferno #01,
Marazm #25,
Ultimathum #01,
Marazm #21,
Hooy Mag #02,
KrNews #11,
Marazm #22,
Marazm #23,
ZX Football 2000 #01,
Codemania #01,
Always #03,
Bugs #02,
IzhNews #08,
Virtual Worlds #01,
Listok #04,
Scenergy #02,
Flash Info #18,
Marazm #16,
Marazm #17,
Zed #01,
Balagan #02,
ZX Format #08,
ZX Power #03,
Shock #01,
Impulse #02,
Deja Vu #03,
ZX Club #08,
ZX Club #06,
Numberology #01,
Marazm #13,
Marazm #12,
Marazm #14,
Gorodok #02,
Zodiac #01,
Marazm #15,
Deja Vu #07,
Marazm #11,
Deja Vu #07,
Playboy #03,
Crazy News #2,
Crazy News #4,
ZX Light #01,
Crazy News #5,
Playboy #02,
ZX News #03,
ZX Review #1-2,
Read Me #02,
Crazy News #3,
Nicron #13,
Read Me #01,
Public Spirit #01,
Faultless #06,
Faultless #05,
ZX Software #01,
Stump #04,
Speccy #07,
Возраждение #0,
Speccy #03,
On-Line #17,
Scene+ #01,
Welcome Press #01,
ZX Konig #04,
Adventurer #01,
Faultless #05,
Faultless #04,
Di Halt #01,
Faultless #01,
Playboy #01,
Crazy News #1,
Faultless #03,
Pioneer #03,
Sinclair Town #02,
ZX Magazine #01,
Eldorado #01,
ZX Magazine #02,
Spectron #01,
ZX News #01,
ZX Konig #02,
200 #W,
Welcome Press #00,
Dune #07,
Subliminal Extacy #01,
Subliminal Extacy #02,
ZX Konig #01,
Subliminal Extacy #00,
Muchomor #01,
Spectrofon #01,
ZX Revija #02,
Outlet #01,
Outlet #1-3