┬I.2.3. Примеры, взятые из жизни Опыт увеличивает нашу мудрость, но не уменьшает нашей глупости. Джош Биллингс Пример номер один Приведем один простой ├пример из жизни. Опишем ситуацию: в дисководе "А" находится закрытый на запись диск. В дисководе "B" - диск с разрешенной записью. В командной строке была допущена ошибка вида: A>copy con batch.bat (перед именем "batch.bat" не было указано имя дисковода "В"). С консоли создали некоторый текстовый файл и нажали клавиши "ctrl"+"z". Естественно, что операционная система попыталась записать эту информацию на дискету, находящуюся в дисководе "А" и в результате сообщила: Write protect error writing drive A: Abort, Retry, Ignore? . Оператор поменял диски местами ( что категорически запрещается де╨ лать ┬ сейчас поймете, почему) и нажал клавишу "R". В результате этого "запрещенного" приема все текстовые файлы потеряли: кто - начало, кто окончание. Возникла паника, так как диск содержал уникальную информа╨ цию. А случилось вот что: операционная система считала ТРФ в оперативную память и произвела необходимые изменения. Затем начала поиск того сек╨ тора каталога, в который можно было бы вписать новое имя создаваемого файла. Номер этого сектора оказался равным 9. Он был загружен в опера╨ тивную память компьютера и MSX-DOS вписала все необходимые данные в ко╨ пию сектора. И только после этого была сделана попытка записать файл на диск. Диск оказался защищенным от записи. Программа выдала сообщение об ошибке. После перестановки дисков со стороны операционной системы не было предринято никаких попыток заново загрузить FAT и Справочник, она сразу (о ужас!) записала все данные на дискету. FAT перестала соот╨ ветствовать реальному расположению файов на диске. Но все было легко восстановить по двум причинам: ┌во-первых,─ до "гибели" файлы на дискете были расположены в идеальном порядке, т.е. не было ни одного "скачка" в ссылках; ┌во-вторых,─ заполненная часть Справочника диска располагалась в двух секторах (7 и 8), а измененный сектор имел номер 9, а это означает, что вся информация о началах файлов сохранилась. Итак,началось восстанавление "погибшей" информации. Вначале мы очис╨ тили ТРФ и записали строгую цепочку последовательных ссылок от начала FAT и до конца последнего файла. Конец последнего файла нашли по следу╨ ющей формуле: Номер_первого_кластера_последнего_файла + (Его_объем div 400h) + 1 , (все вычисления производятся в шестнадцатеричной системе). Распечатали оглавление диска (этого можно не делать) и установили признаки концов файлов в соответствии с каталогом по формуле: Последний_кластер_файла = Начальный_кластер - 1 . Естественно, что начальный_кластер ┬ это ┌первый кластер ├следующего─ ├фай╨ ├ла!─ Потом освободили Справочник от бесполезной информации, находящейся в 9-м секторе и записали оглавление и ТРФ на дискету. На этом восстановление уникальной информации благополучно заверши╨ лось. \/FE А теперь(специально для любителей попрограммировать на языке MSX-BASIC) покажем, как хранится на диске файл с программой, а потом приведем пример восстановления такого файла. Сначала ┬ необходимое введение... \/FN └Таблица програмных команд (PIT ┬ Program Instruction Table)─ PIT ┬ это место в оперативной памяти компьютера, где хранится Ваша программа, преобразованная BASIC-системой во внутренний код. Следующая табличка представляет собой карту памяти слота 0 (слот "BASIC"), в ко╨ тором все изменения, редактирование и запуск программ производятся под управлением интерпретатора языка. \/T0/1 0000h ├┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬│ ┴▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄┴ ┴▄▄▄▄▄▄▄▄▄ ROM (Интерпретатор MSX-BASIC) ▄▄▄▄▄▄▄┴ ┴▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄┴ 8000h ┼┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┘ ┴ Программа на языке BASIC ┴ ┴ ("Program Instruction Table", PIT) ┴ └┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┘ ┴ Простые переменные ("Variable Table") ┴ └┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┘ ┴ Массивы ("Array Variable Table") ┴ └┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┘ ┴ Свободная область ("Free Area") ┴ └┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┘ ┴ Стек ("Stack Area") ┴ └┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┘ ┴ Строковая область ("Character String Area") ┴ └┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┘ ┴ Блок управления файлами ("Files Control Block")┴ F380h ┼┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┴ ┴ Рабочая область ┴ ┴ (системные переменные и таблица ловушек) ┴ FFFFh ┤┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┐ \/T1/1- Таблица PIT обычно начинается по адресу &H8000. Однако ее можно "сдвинуть", изменив значение системной переменной TXTTAB в таблице сис╨ темных переменных. Для помещения PIT с адреса &HА000 достаточно выпол╨ нить следующую программу: 5 'Адрес &HА001, находящийся в двух ячейках с номерами, начиная с &hF676, определяет место, с которого начнется текст программы. 10 POKE &HF676,&H01 'Заполнение младшего байта слова TXTTAB 20 POKE &HF677,&HA0 'Заполнение старшего байта слова TXTTAB 30 POKE &HA000,0 'Первый байт PIT(&HA000) должен быть нулевым! 40 NEW 'Стираем данную программу! Напомним Вам, что адрес &HА001 ( как и любой другой! ) размещается в двух байтах так: \/T0/1 Адрес ┬┬▐ &HF676 &HF677 ░┬┬ Адрес младшего байта ┴ ┴ старшего байта ─┬┬┬┬┬┴┬┬┬┬┬┬┬┬┬┴┬┬┬┬│ Содержимое ┴ ─┬┬┬█┬┬│ ─┬┬┬█┬┬│ ┴ Содержимое младшего ░┬┬┬┬┬ &Н01 ┴ ┴ &HА0 ┬┬┬┬┬▐ старшего байта ┴ ┌┬┬┬┬┬┬┐ ┌┬┬┬┬┬┬┐ ┴ байта ┌┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┐ \/T1/1- Очевидно, что в результате этих "манипуляций" размер свободной об╨ ласти уменьшится на &H2000 байтов (&HA000-&H8000=&H2000), и область, расположенная между &H8000 и началом PIT, будет защищена от "вторжения" программ на MSX-BASIC. Ясно, что величина PIT зависит от размера текста программы. После выполнения данной программы нажмите кнопку сброса "RE╨ SET". А теперь мы поведаем Вам о том, как хранится программа, написан╨ ная на языке BASIC в PIT. \/T0/1 ─┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬│ ┴ Все строки программы на MSX-BASIC начинаются с ┼2-байтного указателя.─┴ ┴ За этим указателем идут ┼два байта, содержащие номер строки.─ ┴ ┴ Затем идет ┼текст строки с─ последующим ┼нулевым байтом.─ ┴ ┴ ┼За последней строкой следуют два─ дополнительных ┼нулевых байта─, ад╨┴ ┴ рес которых находится в указателе последней строки программы. ┴ ┴ Цифры и зарезервированные служебные слова записываются во внутрен╨┴ ┴ нем коде (один или два байта на слово, цифру). ┴ ┴ Для остального текста используется код ASCII. ┴ ┌┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┐ \/T1/1- Введем в память следующую короткую программу: 10 B=5 20 END Теперь прочитаем, что же реально содержится в PIT, используя в не╨ посредственном режиме команду PRINT HEX$(PEEK(A)) , где значение пере╨ менной А (адреса) изменяется от &H8000 до &H8010. Вы обнаружите: \/T0/1 ─┬┬┬┬┬┬┬┬┬┬┬├┬┬┬┬┬┬┬┬┬┬┬┬┬├┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬│ ┴ Значение А┴HEX$(PEEK(A))┴ юКомментарии─ ┴ └┬┬┬┬┬┬┬┬┬┬┬┼┬┬┬┬┬┬┬┬┬┬┬┬┬┼┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┘ ┴ 8000 ┴ 0 ┴ Первый байт PIT всегда нулевой ┴ └┬┬┬┬┬┬┬┬┬┬┬┼┬┬┬┬┬┬┬┬┬┬┬┬┬┼┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┘ ┴╧╧ 8001 ╧╧┴ 09 ┴ Ссылка на начало следующей строки ┴ ┴╧╧ 8002 ╧╧┴ 80 ┴ (указатель следующей строки находится по ┴ ┴╧╧╧╧╧╧╧╧╧╧╧┴ ┴ адресу &Н8009) ┴ └┬┬┬┬┬┬┬┬┬┬┬┼┬┬┬┬┬┬┬┬┬┬┬┬┬┼┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┘ ┴ 8003 ┴ А ┴ "Визуальный" номер первой строки ┴ ┴ 8004 ┴ 0 ┴ &H000А = 10 ┴ └┬┬┬┬┬┬┬┬┬┬┬┼┬┬┬┬┬┬┬┬┬┬┬┬┬┼┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┘ ┴ 8005 ┴ 42 ┴ Шестнадцатеричный код ASCII буквы "B" ┴ ┴ 8006 ┴ EF ┴ Внутренний код знака равенства ┴ ┴ 8007 ┴ 16 ┴ Внутренний код цифры 5 ┴ ┴ 8008 ┴ 0 ┴ Конец первой строки ┴ └┬┬┬┬┬┬┬┬┬┬┬┼┬┬┬┬┬┬┬┬┬┬┬┬┬┼┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┘ ┴╧╧ 8009 ╧╧┴ 0F ┴ Ссылка на начало следующей строки ┴ ┴╧╧ 800A ╧╧┴ 80 ┴ (указатель следующей строки находится по ┴ ┴╧╧╧╧╧╧╧╧╧╧╧┴ ┴ адресу &Н800F) ┴ └┬┬┬┬┬┬┬┬┬┬┬┼┬┬┬┬┬┬┬┬┬┬┬┬┬┼┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┘ ┴ 800B ┴ 14 ┴ "Визуальный" номер первой строки ┴ ┴ 800C ┴ 00 ┴ &H0014 = 20 ┴ └┬┬┬┬┬┬┬┬┬┬┬┼┬┬┬┬┬┬┬┬┬┬┬┬┬┼┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┘ ┴ 800D ┴ 81 ┴ Внутренний код оператора END ┴ ┴ 800Е ┴ 00 ┴ Конец второй строки ┴ └┬┬┬┬┬┬┬┬┬┬┬┼┬┬┬┬┬┬┬┬┬┬┬┬┬┼┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┘ ┴ 800F ┴ 0 ┴ Конец программы ┴ ┴ 8010 ┴ 0 ┴ ┴ ┌┬┬┬┬┬┬┬┬┬┬┬┤┬┬┬┬┬┬┬┬┬┬┬┬┬┤┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┐ \/T1/1- Теперь, надеемся, Вам стало ясно, как можно изменить программу с по╨ мощью оператора POKE. Попробуйте выполнить следующее: POKE &H8005,&H41 '41 - шестнадцатеричный код ASCII буквы "A" POKE &H8007,&H17 '17 ┬ внутренний код цифры "6" А теперь наберите команду LIST, затем нажмите клавишу░┬┐ и ...: 10 A=6 20 END Теперь Вам ясно, что "инструкции" PEEK и POKE таят в себе поистине безграничные возможности. По существу, они позволяют нам распоряжаться памятью компьютера по своему усмотрению. Например, они позволяют нам при желании подшутить над компьютером: если известно, где хранится программа, то мы можем сделать так, что после одной из строк программы окажется строка с меньшим номером. Пусть исходная программа имеет вид: 10 PRINT 4 20 PRINT 2 Вам, конечно, уже известно, что строки программы на языке MSX-BASIC начинаются с двухбайтного указателя, за которым следуют два байта, со╨ держащие номер строки. Поэтому вначале выполним команду: PRINT HEX$(PEEK(&H8002));" ";HEX$(PEEK(&H8001)) 80 9 Ok Таким образом, указатель следующей (с номером 20) строки располага╨ ется в ячейках с адресами &H8009 и &H800A, а, следовательно, номер вто╨ рой строки находится в ячейках с адресами &H800B и &H800C . Проверим этот факт: PRINT HEX$(PEEK(&H800C));" ";HEX$(PEEK(&H800B)) ─┬┬▐ PRINT &H14 0 14 ┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┐ 20 Ok Ok А теперь: POKE &H800B,1 Ok list 10 PRINT 4 1 PRINT 2 Ok Программа действует, но строку с номером 1 нельзя ни стереть, ни ис╨ править. Вы можете написать еще одну 1-ю строку и даже новую 20-ю стро╨ ку! Однако не пытайтесь изменять с помощью оператора POKE длину строки или путать указатели: результат будет катaстрофическим! Ну а если Вы нечаянно нажали RESET, - не спешите отчаиваться! Вашу программу еще можно спасти. Это очень легко сделать, набрав ту же ко╨ манду POKE &H8001,1 а затем auto . На экране появятся строки: 10* 20* и так далее ... Строки с "*" - спасенные. Теперь достаточно "скомандовать": LIST и... о, чудо! Но это еще не все! Оказывается, спасены и все строки меж╨ ду теми, номера которых не делятся нацело на 10! Если же Вы захотите защитить свою программу от запуска(команды RUN), то примените в непосредственном режиме команду: POKE &H8000,1 Ok (разумеется, Ваша программа должна располагаться с адреса &H8000). По команде 'SAVE' компьютер выполняет следующие простые действия... \/T0/1 ─┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬│ ┴ Программа сохраняется в файле на диске таким образом: ┴ ┴ ═) значение первого байта файла устанавливается в &HFF и ┴ ┴ ║) текст программы во внутреннем представлении копируется ┴ ┴ из PIT на дискету. ┴ ┌┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┐ \/T1/1- Надеемся, что эти примеры немного развлекли Вас и переходим к цели нашего повествования... Пример номер два На диске находилась сложная программа, сохраненная во внутреннем ко╨ де. Однажды "Некто" под тем же именем сохранил пустую программу. Копии большой программы не было, и по этому ее нужно было восстановить во что бы то ни стало. При просмотре диска мы обнаружили некоторые интересные вещи: 1) объем файла стал равным трем байтам (содежимое: FF,00,00); 2) за этими тремя байтами следовали еще 253 неизвестных байта; 3) остальная информация сохранилась полностью, восстановления требо╨ вали только FAT и директории. Программу можно было попытаться спасти,но вызывал затруднения следу╨ ющий нюанс: содержимое "испорченного" сектора будет "портить" всю прог╨ рамму; при использовании команды LIST на экране может появиться все, что угодно, но только не Ваша программа! Как избежать этого? Логично было бы вручную исправить начальный сек╨ тор файла таким образом, чтобы не потерять ни одной ссылки, ни одного байта из оставшейся части программы. Восстановление началось с того, что мы определили цепочку ссылок в FAT, вписали прежний размер файла в каталог и сохранили все это на дис╨ ке. Затем необходимо было чем-то заполнить первые 256 байт, чтобы потом эту программу можно было загрузить в BASIC-системе. Помня, что в строке может быть не более 255 символов, мы сделали 2 строчки, заполнили их кодами &HF1 (внутренний код символа "+") и расставили ссылки на следу╨ ющие строки. Весь сектор (256 байт) был заполнен примерно таким обра╨ зом: \/T0/1 ─┬┬┬┬┬┬┬┬┬┬┬┬├┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬│ ┴ Адрес байта┴ юСодержимое─ ┴ └┬┬┬┬┬┬┬┬┬┬┬┬┼┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┘ ┴ 000 ┴ FF ┬ первый стандартный для ┴ ┴ ┴ файлов на BASIC байт ┴ └┬┬┬┬┬┬┬┬┬┬┬┬┼┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┘ ┴ 001 ┴ 05 │ 8105 ┬ адрес след. строки ┴ ┴ 002 ┴ 81 ┐ ┴ └┬┬┬┬┬┬┬┬┬┬┬┬┼┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┘ ┴ 003 ┴ 01 │ 0001 ┬ номер строки ┴ ┴ 004 ┴ 00 ┐ ┴ └┬┬┬┬┬┬┬┬┬┬┬┬┼┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┘ ┴ 005 ┴ F1 │ ┴ ┴ ┴ ┴ ┴ ┴ ╧╧╧ ┴ ╧╧╧ ┴ строка из 255 символов "+" ┴ ┴ ┴ ┴ ┴ ┴ 103 ┴ F1 ┐ ┴ ┴ 104 ┴ 00 ┬ конец строки ┴ └┬┬┬┬┬┬┬┬┬┬┬┬┼┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┘ ┴ 105 ┴ FC │ 81FC ┬ адрес след. строки ┴ ┴ 106 ┴ 81 ┐ ┴ └┬┬┬┬┬┬┬┬┬┬┬┬┼┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┘ ┴ 107 ┴ 02 │ 0002 ┬ номер строки ┴ ┴ 108 ┴ 00 ┐ ┴ └┬┬┬┬┬┬┬┬┬┬┬┬┼┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┘ ┴ 109 ┴ F1 │ ┴ ┴ ┴ ┴ ┴ ┴ ╧╧╧ ┴ ╧╧╧ ┴ строка из 242 символов "+" ┴ ┴ ┴ ┴ ┴ ┴ 1FA ┴ F1 ┐ ┴ ┴ 1FB ┴ 00 ┬ конец строки ┴ └┬┬┬┬┬┬┬┬┬┬┬┬┼┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┘ ┴ 1FC ┴ ?? │ 82?? ┬ неизвестный адрес ┴ ┴ 1FD ┴ 82 ┐ след. строки (его определяют ┴ ┴ ┴ по содержимому 2-го сектора) ┴ └┬┬┬┬┬┬┬┬┬┬┬┬┼┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┘ ┴ 1FE ┴ 03 │ 0003 ┬ номер строки ┴ ┴ 1FF ┴ 00 ┐ ┴ ┌┬┬┬┬┬┬┬┬┬┬┬┬┤┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┐ \/T1/1- Обратите внимание на тот факт, что адресу 1FC должна лежать ссылка на существующую строку программы, поэтому перед тем, как заполнить этот байт, Вы должны внимательно просмотреть начало следующего сектора (приблизительно 252 байта) и найти адрес (в разделе ENTRY) байта, сто╨ ящего перед байтом с содержимым 82h! Только после этого можно загружать программу в BASIC и, уничтожив две первые строки, вспоминать, каким было начало Вашей программы!